After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 625442 - pulsesink: crash - pa_threaded_mainloop_stop is called from the pa thread
pulsesink: crash - pa_threaded_mainloop_stop is called from the pa thread
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
0.10.22
Other Linux
: Normal critical
: 0.10.25
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2010-07-27 22:30 UTC by gudake
Modified: 2010-08-14 13:16 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description gudake 2010-07-27 22:30:18 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 ()
Comment 1 Sebastian Dröge (slomo) 2010-07-28 05:40:44 UTC
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 ***
Comment 2 gudake 2010-07-28 19:47:32 UTC
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.
Comment 3 gudake 2010-07-28 20:37:29 UTC
sorry about the last message, it seems to be fixed in trunk. pa_threaded_mainloop_stop() is removed from finalize function