GNOME Bugzilla – Bug 625442
pulsesink: crash - pa_threaded_mainloop_stop is called from the pa thread
Last modified: 2010-08-14 13:16:54 UTC
If gst_pulseringbuffer_stop is immediately followed by unreffing the pulsesink, there is a chance that mainloop_leave_defer_cb decreases pulsesink refcount from 1 to 0 and calling pa_threaded_mainloop_stop(), this is prohibit in pulseaudio and causing assertion failure: pa_threaded_mainloop_stop() should not be called from pa worker thread pulseaudio source code: pa_assert(!in_worker(m)) is where crashes void pa_threaded_mainloop_stop(pa_threaded_mainloop *m) { pa_assert(m); if (!m->thread || !pa_thread_is_running(m->thread)) return; /* Make sure that this function is not called from the helper thread */ pa_assert(!in_worker(m)); pa_mutex_lock(m->mutex); pa_mainloop_quit(m->real_mainloop, 0); pa_mutex_unlock(m->mutex); pa_thread_join(m->thread); } example crashing stack trace where pa_threaded_mainloop_stop() is triggered by mainloop_leave_defer_cb() inside pulse worker thread. #00 pc 2c62ac0c(20c0c) in /usr/lib/libpulse.so.0.7.1/pa_threaded_mainloop_stop () #01 pc 2c5f8e28(ce28) in /usr/lib/gstreamer-0.10/libgstpulse.so/gst_pulsesink_finalize () #02 pc 2b27c4b0(c4b0) in /usr/lib/libgobject-2.0.so.0.1600.6/g_object_unref () #03 pc 2c5f5f44(9f44) in /usr/lib/gstreamer-0.10/libgstpulse.so/mainloop_leave_defer_cb () #04 pc 2c61ef08(14f08) in /usr/lib/libpulse.so.0.7.1/once_callback () #05 pc 2c61ddfc(13dfc) in /usr/lib/libpulse.so.0.7.1/pa_mainloop_dispatch () #06 pc 2c61e1f0(141f0) in /usr/lib/libpulse.so.0.7.1/pa_mainloop_iterate () #07 pc 2c61e2b0(142b0) in /usr/lib/libpulse.so.0.7.1/pa_mainloop_run () #08 pc 2c62ad70(20d70) in /usr/lib/libpulse.so.0.7.1/thread () #09 pc 2c651ec0(47ec0) in /usr/lib/libpulse.so.0.7.1/internal_thread_func () #10 pc 2aae2774(6774) in /lib/libpthread-2.8.so/start_thread () #11 pc 2b1d7af4(d6af4) in /lib/libc-2.8.so/__clone ()
That's fixed some time ago. commit a8103facc59b9dde07ee95d026c3fd2323e278bb Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> Date: Mon May 17 17:17:01 2010 +0200 pulse: Don't lock the mainloop in NULL commit e69ba0f94f475975cfa33d651a56fc1567c0238b Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> Date: Thu May 6 13:57:01 2010 +0200 pulsesink: Allocate and free the custom clock in NULL<->READY commit 5332287e2d8f9dc7b32da0f6618a0730bd98513a Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> Date: Thu May 6 13:51:59 2010 +0200 pulsesink: Create and free the PA mainloop in NULL->READY/READY->NULL This fixes a race condition, when stopping the mainloop during finalization is done from a mainloop callback. Fixes bugs #614765 and #590662. *** This bug has been marked as a duplicate of bug 614765 ***
this is not a duplication of bug 614765, it's introduced in fixing 614765. What bug 614765 did is ref pulsesink before firing the pa_mainloop_api_once(), and unref the pulsesink in the callback. This makes sure that the pulse callback function is always called on a valid pulsesink. BUT it introduce a new problem, if the pulse callback function is the LAST one being called, it will finalize the pulsesink and calling pa_threaded_mainloop_stop() from the pathread, which is prohibited, because if you take a look of pa_threaded_mainloop_stop(), it calls pthread_join(), you CANNOT pthread_join() with the same thread.
sorry about the last message, it seems to be fixed in trunk. pa_threaded_mainloop_stop() is removed from finalize function