Hi,

when developing PulseAudio clients with a threaded mainloop (on OS X
in my case), I came across an effect which causes my client to crash
out early with a failed assertion like

  Assertion 'c->defer_event == e' failed at
pulsecore/socket-client.c:172, function connect_defer_cb(). Aborting.

Searching for this issue didn't reveal much, except that there has
been other people seeing this:

  https://bugzilla.redhat.com/show_bug.cgi?id=497650

Looking at the code, it seems obvious that this is a simple race
condition. In do_connect(),  pulsecore/socket-client.c:210, we have
this:

  c->defer_event = c->mainloop->defer_new(c->mainloop, connect_defer_cb, c);

and defer_new() calls pa_mainloop_wakeup() before it returns. So in a
threaded mainloop, it could be that the defered event has already been
dispatched before defer_new() returns.
However, c->defer_event is assigned *after* defer_new() returns, and
hence the assertion fails consequently. The same counts for
defer_enable() in some cases, as the event is enabled by default and
could have been executed already, so disabling it after the mainloop
was woken up has no effect.

As this seems so obvious, and the code has been around for some years,
I wonder whether I miss anything obvious here. Is there any mutex
(which doesn't work yet on OS X) that should protect the mainloop from
this race? I attached a patch ready to fix this issue for me, but I'm
not sure whether there is more code left which fails for similar
assumptions.

Thanks,
Daniel

Attachment: 0001-mainloop-api-fix-race-condition-in-defer_new.patch
Description: Binary data

_______________________________________________
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss

Reply via email to