Re: [pulseaudio-discuss] libpulse deadlock

2011-07-21 Thread Colin Guthrie
'Twas brillig, and Rémi Denis-Courmont at 18/07/11 17:36 did gyre and
gimble:
>   Hello,
> 
> I might have missed something obvious but there seems to be a race condition 
> resulting in a deadlock in libpulse 0.9.22 (Debian).
> 
> I have stream with prebuf disabled (zero). When the Close() function below 
> gets called, if the stream is _not_ corked, the pa_stream_drain() callback 
> never gets called, so pa_threaded_mainloop_wait() never returns and the whole 
> process jams.
> 
> This seems timing dependent: if I put a gdb breakpoint on 
> pa_operation_get_state() then continue, the callback does get called and the 
> process does not get stuck on the condition variable. There is also no 
> problem 
> if the stream is corked, in which case we use pa_stream_flush() instead of 
> pa_stream_drain().

Thanks for creating the bug. It'll be easier to track now. :)

https://bugs.freedesktop.org/show_bug.cgi?id=39459

Col

-- 

Colin Guthrie
gmane(at)colin.guthr.ie
http://colin.guthr.ie/

Day Job:
  Tribalogic Limited [http://www.tribalogic.net/]
Open Source:
  Mageia Contributor [http://www.mageia.org/]
  PulseAudio Hacker [http://www.pulseaudio.org/]
  Trac Hacker [http://trac.edgewall.org/]

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] libpulse deadlock

2011-07-18 Thread Rémi Denis-Courmont
Hello,

I might have missed something obvious but there seems to be a race condition 
resulting in a deadlock in libpulse 0.9.22 (Debian).

I have stream with prebuf disabled (zero). When the Close() function below 
gets called, if the stream is _not_ corked, the pa_stream_drain() callback 
never gets called, so pa_threaded_mainloop_wait() never returns and the whole 
process jams.

This seems timing dependent: if I put a gdb breakpoint on 
pa_operation_get_state() then continue, the callback does get called and the 
process does not get stuck on the condition variable. There is also no problem 
if the stream is corked, in which case we use pa_stream_flush() instead of 
pa_stream_drain().

The code follows:

static void stream_success_cb(pa_stream *s, int success, void *userdata)
{
pa_threaded_mainloop *mainloop = userdata;

fprintf(stderr, "DONE: %d\n", success);
pa_threaded_mainloop_signal(mainloop, 0);
(void) s;
(void) success;
}

/* ... */

static void Close(vlc_object_t *obj)
{
aout_instance_t *aout = (aout_instance_t *)obj;
aout_sys_t *sys = aout->output.p_sys;
pa_threaded_mainloop *mainloop = sys->mainloop;
pa_context *ctx = sys->context;
pa_stream *s = sys->stream;

/* ... */

pa_threaded_mainloop_lock(mainloop);
if (s != NULL) {
pa_operation *op;

if (pa_stream_is_corked(s) > 0)
/* Stream paused: discard all buffers */
op = pa_stream_flush(s, stream_success_cb, mainloop);
else
/* Stream playing: wait until buffers are played */
op = pa_stream_drain(s, stream_success_cb, mainloop);
if (likely(op != NULL)) {
while (pa_operation_get_state(op) == PA_OPERATION_RUNNING) {
fprintf(stderr, "waiting\n");
pa_threaded_mainloop_wait(mainloop);
}
pa_operation_unref(op);
}

pa_stream_disconnect(s);
pa_stream_unref(s);
}
if (ctx != NULL)
pa_context_unref(ctx);
pa_threaded_mainloop_unlock(mainloop);
pa_threaded_mainloop_free(mainloop);
free(sys);
}

-- 
Rémi Denis-Courmont
http://www.remlab.net/
http://fi.linkedin.com/in/remidenis
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss