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 330748 - deadlock in base audio sink on playing->paused state change
deadlock in base audio sink on playing->paused state change
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-base
git master
Other Linux
: Urgent blocker
: 0.10.6
Assigned To: Wim Taymans
GStreamer Maintainers
: 326086 331225 332214 (view as bug list)
Depends on: 326311
Blocks:
 
 
Reported: 2006-02-11 03:45 UTC by Jonathan Matthew
Modified: 2006-03-17 17:49 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
don't start playback when we pause (3.93 KB, patch)
2006-03-17 17:08 UTC, Wim Taymans
none Details | Review

Description Jonathan Matthew 2006-02-11 03:45:44 UTC
Occasionally I experience deadlocks in rhythmbox when changing songs.  All rhythmbox is doing is calling gst_element_set_state (playbin, GST_STATE_READY).  This is with fairly recent (~2 days) CVS checkouts.  It doesn't seem to happen on a different machine running core 0.10.3, -plugins-base 0.10.2.

[Switching to thread 5 (Thread -1276630096 (LWP 7241))]#0  0xffffe410 in __kernel_vsyscall ()
(gdb) where
  • #0 __kernel_vsyscall
  • #1 pthread_cond_wait
    from /lib/tls/i686/cmov/libpthread.so.0
  • #2 wait_segment
    at gstringbuffer.c line 1077
  • #3 gst_ring_buffer_commit
    at gstringbuffer.c line 1179
  • #4 gst_base_audio_sink_render
    at gstbaseaudiosink.c line 596
  • #5 gst_base_sink_render_object
    at gstbasesink.c line 858
  • #6 gst_base_sink_queue_object_unlocked
    at gstbasesink.c line 1021
  • #7 gst_base_sink_chain_unlocked
    at gstbasesink.c line 1266
  • #8 gst_base_sink_chain
    at gstbasesink.c line 1301
  • #9 gst_pad_chain
    at gstpad.c line 3172
  • #10 gst_proxy_pad_do_chain
    at gstghostpad.c line 205
  • #11 gst_pad_chain
    at gstpad.c line 3172
  • #12 gst_pad_push
    at gstpad.c line 3271
  • #13 gst_base_transform_chain
    at gstbasetransform.c line 1305
  • #14 gst_pad_chain
    at gstpad.c line 3172
  • #15 gst_pad_push
    at gstpad.c line 3271
  • #16 gst_base_transform_chain
    at gstbasetransform.c line 1305
  • #17 gst_pad_chain
    at gstpad.c line 3172
  • #18 gst_proxy_pad_do_chain
    at gstghostpad.c line 205
  • #19 gst_pad_chain
    at gstpad.c line 3172
  • #20 gst_pad_push
    at gstpad.c line 3271
  • #21 gst_queue_loop
    at gstqueue.c line 760
  • #22 gst_task_func
    at gsttask.c line 186
  • #23 g_thread_pool_thread_proxy
    at gthreadpool.c line 114
  • #24 g_thread_create_proxy
    at gthread.c line 564
  • #25 start_thread
    from /lib/tls/i686/cmov/libpthread.so.0
  • #26 clone
    from /lib/tls/i686/cmov/libc.so.6
  • #0 __kernel_vsyscall
  • #1 __lll_mutex_lock_wait
    from /lib/tls/i686/cmov/libpthread.so.0
  • #2 _L_mutex_lock_29
    from /lib/tls/i686/cmov/libpthread.so.0
  • #3 __PRETTY_FUNCTION__.16627
    from /home/jonathan/sw/gstreamer-cvs//lib/libgstbase-0.10.so.0
  • #4 ??
  • #5 ??
  • #6 ??
  • #7 ??
  • #8 ??
    from /home/jonathan/sw/gstreamer-cvs//lib/libgstbase-0.10.so.0
  • #9 ??
  • #10 index_resolver.15692
    from /home/jonathan/sw/gstreamer-cvs//lib/libgstreamer-0.10.so.0
  • #11 ??
  • #12 gst_base_sink_change_state
    at gstbasesink.c line 1780
  • #13 gst_base_sink_change_state
    at gstbasesink.c line 1780
  • #14 gst_base_audio_sink_change_state
    at gstbaseaudiosink.c line 738
  • #15 gst_element_change_state
    at gstelement.c line 2171
  • #16 gst_element_set_state_func
    at gstelement.c line 2133
  • #17 gst_element_set_state
    at gstelement.c line 2043
  • #18 gst_bin_change_state_func
    at gstbin.c line 1710
  • #19 gst_gconf_audio_sink_change_state
    at gstgconfaudiosink.c line 172
  • #20 gst_element_change_state
    at gstelement.c line 2171
  • #21 gst_element_set_state_func
    at gstelement.c line 2133
  • #22 gst_element_set_state
    at gstelement.c line 2043
  • #23 gst_bin_change_state_func
    at gstbin.c line 1710
  • #24 gst_element_change_state
    at gstelement.c line 2171
  • #25 gst_element_set_state_func
    at gstelement.c line 2133
  • #26 gst_element_set_state
    at gstelement.c line 2043
  • #27 gst_bin_change_state_func
    at gstbin.c line 1710
  • #28 gst_pipeline_change_state
    at gstpipeline.c line 375
  • #29 gst_play_base_bin_change_state
    at gstplaybasebin.c line 1793
  • #30 gst_play_bin_change_state
    at gstplaybin.c line 1310
  • #31 gst_element_change_state
    at gstelement.c line 2171
  • #32 gst_element_set_state_func
    at gstelement.c line 2133
  • #33 gst_element_set_state
    at gstelement.c line 2043
  • #0 __kernel_vsyscall
  • #1 pthread_cond_wait
    from /lib/tls/i686/cmov/libpthread.so.0
  • #2 audioringbuffer_thread_func
    at gstaudiosink.c line 200
  • #3 g_thread_create_proxy
    at gthread.c line 564
  • #4 start_thread
    from /lib/tls/i686/cmov/libpthread.so.0
  • #5 clone
    from /lib/tls/i686/cmov/libc.so.6
  • #0 __kernel_vsyscall
  • #1 pthread_cond_wait
    from /lib/tls/i686/cmov/libpthread.so.0
  • #2 gst_queue_chain
    at gstqueue.c line 679
  • #3 gst_pad_chain
    at gstpad.c line 3172
  • #4 gst_pad_push
    at gstpad.c line 3271
  • #5 gst_stream_selector_chain
    at gststreamselector.c line 354
  • #6 gst_pad_chain
    at gstpad.c line 3172
  • #7 gst_proxy_pad_do_chain
    at gstghostpad.c line 205
  • #8 gst_pad_chain
    at gstpad.c line 3172
  • #9 gst_pad_push
    at gstpad.c line 3271
  • #10 gst_mad_chain
    at gstmad.c line 1594

My vague guess as to what's happened:
- thread 5 waits for a new segment from the ring buffer
- thread 1 calls set_state, baseaudiosink calls ring_buffer_pause, then goes into base sink's change state function which blocks on the preroll lock (held by thread 5)
- thread 2 calls ring_buffer_prepare_read, which returns FALSE because the ring buffer is paused, and goes on to wait on the audio ring buffer condition variable

so, now thread 2 will never advance the ring buffer, so the thread 5 will never be unblocked, so the thread 1 will never get the preroll lock, and the state change will never return.
Comment 1 Jan Schmidt 2006-02-11 13:34:50 UTC
CC'ing Wim for comment
Comment 2 Wim Taymans 2006-02-13 11:35:30 UTC
-core 0.10.3 and -base 0.10.2 can cause random audiosink delays and lockups when doing state changes.

Can you test with -base 0.10.3 against -core 0.10.3?
Comment 3 Jonathan Matthew 2006-02-13 13:05:59 UTC
I've upgraded to CVS HEAD for core and -base, and I've been testing it for a while.  I was just about to close this bug when it happened again, with almost exactly the same stack traces.
Comment 4 Wim Taymans 2006-02-13 19:07:45 UTC
ok, found how it could happen, _pause does not signal so the thread stays blocked in wait_segment, not knowing about the state change. patch comming up soon...
Comment 5 Wim Taymans 2006-02-14 13:49:19 UTC
Can you retest with current -base CVS version?
Comment 6 Jonathan Matthew 2006-02-14 20:36:13 UTC
I'm testing current -base CVS at the moment.  Since I don't have a reliable way of triggering the bug, I'll wait a couple of days before closing the bug.
Comment 7 James "Doc" Livingston 2006-02-15 09:49:32 UTC
*** Bug 331225 has been marked as a duplicate of this bug. ***
Comment 8 Jonathan Matthew 2006-02-17 23:30:32 UTC
I haven't seen it since, so I'm pretty confident it's fixed.
Comment 9 Jonathan Matthew 2006-02-20 09:20:31 UTC
Or not.  It's still happening, with the same stack traces for the three deadlocked threads.
Comment 10 Wim Taymans 2006-03-07 09:48:22 UTC
*** Bug 326086 has been marked as a duplicate of this bug. ***
Comment 11 Jonathan Matthew 2006-03-08 20:06:59 UTC
*** Bug 332214 has been marked as a duplicate of this bug. ***
Comment 12 Wim Taymans 2006-03-17 12:48:51 UTC
can only sanely do this if #326311 is fixed
Comment 13 Wim Taymans 2006-03-17 17:08:09 UTC
Created attachment 61453 [details] [review]
don't start playback when we pause

Added new method to enable/disable automatic start of the ringbuffer. This solves the race of the ringbuffer starting because it is filled and a state change function performing a _pause().
Comment 14 Wim Taymans 2006-03-17 17:49:08 UTC
        * gst-libs/gst/audio/gstbaseaudiosink.c:
        (gst_base_audio_sink_change_state):
        * gst-libs/gst/audio/gstringbuffer.c: (wait_segment),
        (gst_ring_buffer_may_start):
        * gst-libs/gst/audio/gstringbuffer.h:
        Only start playback if we are playing.
        should fix #330748.