diff options
| author | Federico Mena-Quintero <federico@ximian.com> | 2009-04-19 03:24:53 +0200 | 
|---|---|---|
| committer | Lennart Poettering <lennart@poettering.net> | 2009-04-19 03:24:53 +0200 | 
| commit | 9b75398f448af1a15a8e2859d0d115875e3b6fef (patch) | |
| tree | e66c80637874e4d1eeadbb83e3d5adfae16e9be7 /src/pulse.c | |
| parent | ad95e65e46aba26adb125433cf9a10fe5d0275a5 (diff) | |
pulse: don't hang when operation gets canceled
Handle properly when a sample play operation gets canceled.
http://bugs.freedesktop.org/show_bug.cgi?id=21263
Diffstat (limited to 'src/pulse.c')
| -rw-r--r-- | src/pulse.c | 25 | 
1 files changed, 23 insertions, 2 deletions
| diff --git a/src/pulse.c b/src/pulse.c index 3cd4b2a..c959719 100644 --- a/src/pulse.c +++ b/src/pulse.c @@ -770,6 +770,8 @@ int driver_play(ca_context *c, uint32_t id, ca_proplist *proplist, ca_finish_cal          /* Ok, this sample has an event id, let's try to play it from the cache */          for (;;) { +            ca_bool_t canceled; +              pa_threaded_mainloop_lock(p->mainloop);              /* Let's try to play the sample */ @@ -779,16 +781,35 @@ int driver_play(ca_context *c, uint32_t id, ca_proplist *proplist, ca_finish_cal                  goto finish;              } -            while (pa_operation_get_state(o) != PA_OPERATION_DONE) +            for (;;) { +                pa_operation_state_t state = pa_operation_get_state(o); + +                if (state == PA_OPERATION_DONE) { +                    canceled = FALSE; +                    break; +                } else if (state == PA_OPERATION_CANCELED) { +                    canceled = TRUE; +                    break; +                } +                  pa_threaded_mainloop_wait(p->mainloop); +            }              pa_operation_unref(o);              pa_threaded_mainloop_unlock(p->mainloop); +            /* The operation might have been canceled due to connection termination */ +            if (canceled) { +                ret = CA_ERROR_DISCONNECTED; +                goto finish; +            } +              /* Did we manage to play the sample or did some other error occur? */ -            if (out->error != CA_ERROR_NOTFOUND) +            if (out->error != CA_ERROR_NOTFOUND) { +                ret = out->error;                  goto finish; +            }              /* Hmm, we need to play it directly */              if (cache_control != CA_CACHE_CONTROL_PERMANENT) | 
