GNOME Bugzilla – Bug 556986
pulsesink deadlocks when raising an error
Last modified: 2009-03-03 11:32:30 UTC
To reproduce: $ gst-launch audiotestsrc ! pulsesink - Kill you pulse server - gst-launch tries to go into pause but hangs there Backtrace: arting program: /usr/bin/gst-launch-0.10 audiotestsrc \! pulsesink [Thread debugging using libthread_db enabled] [New Thread 0x480231a0 (LWP 23892)] [New Thread 0x489e24d0 (LWP 23895)] Setting pipeline to PAUSED ... [New Thread 0x491e24d0 (LWP 23896)] [Thread 0x491e24d0 (LWP 23896) exited] [New Thread 0x491e24d0 (LWP 23897)] Pipeline is PREROLLING ... [New Thread 0x4d9e34d0 (LWP 23898)] Pipeline is PREROLLED ... Setting pipeline to PLAYING ... New clock: GstAudioSinkClock ERROR: from element /GstPipeline:pipeline0/GstPulseSink:pulsesink0: Disconnected: Conn ection terminated Additional debug info: pulsesink.c(684): gst_pulsesink_write (): /GstPipeline:pipeline0/GstPulseSink:pulsesin k0 Execution ended after 3680822000 ns. Setting pipeline to PAUSED ... ^C Program received signal SIGINT, Interrupt.
+ Trace 208397
Thread 1208103328 (LWP 23892)
Thread 5 (Thread 0x4d9e34d0 (LWP 23898))
Thread 4 (Thread 0x491e24d0 (LWP 23897))
Thread 1 (Thread 0x480231a0 (LWP 23892))
This is with -plugins-good 0.10.10.3
There's a locking order problem here. Pulsesink is holding the pulse mainloop lock while throwing the element error, which tries to take the object lock and read the object name. One of the other threads is attempting to acquire the pulseaudio lock while holding the element object lock (the set_state() thread, I imagine), leading to deadlock. The fix is probably to ensure that we drop the pulseaudio mainloop lock in all cases before throwing an error.
After unlocking the pulse main loop before throwing any error messages it still deadlocks the same way.
This is fixed by these two changes: 2009-01-05 Wim Taymans <wim.taymans@collabora.co.uk> * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_change_state): Avoid holding the OBJECT_LOCK when calling ringbuffer functions that take the ringbuffer lock because rinbuffer lock > OBJECT_LOCK. We can do this because the async_play method is deprecated and usually not called anymore. 2009-01-05 Sebastian Dröge <sebastian.droege@collabora.co.uk> * ext/pulse/pulsesink.c: (gst_pulsesink_destroy_stream): Don't wait for the pulse mainloop when destroying the stream. Fixes a deadlock when the pulsedaemon goes away while pulsesink is PLAYING. Fixes bug #556986.
*** Bug 573562 has been marked as a duplicate of this bug. ***