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 744040 - bin: Deadlock when sending event
bin: Deadlock when sending event
Status: RESOLVED OBSOLETE
Product: GStreamer
Classification: Platform
Component: gstreamer (core)
git master
Other Linux
: Normal normal
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on: 760532
Blocks:
 
 
Reported: 2015-02-05 13:19 UTC by Jan Schmidt
Modified: 2018-11-03 12:25 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Test leading to deaklock (1.62 KB, text/x-csrc)
2015-10-20 19:11 UTC, Nicolas Dufresne (ndufresne)
  Details
element: Don't hold state lock all the time while sending an event (1002 bytes, patch)
2015-10-28 16:09 UTC, Sebastian Dröge (slomo)
none Details | Review

Description Jan Schmidt 2015-02-05 13:19:46 UTC
Encountered a locking order problem while doing some playing around in the playback test app: A flush occuring during a step leads to a basesink deadlock.

The sink element is posting STEP_DONE, holding the STREAM_LOCK. The app sends a new step event from the sync bus handler, which tries to take the STATE_LOCK.

Meanwhile, the app has sent a flushing seek, which is holding the STATE_LOCK, and trying to acquire the STREAM_LOCK.

It seems either basesink should drop the stream lock while sending the STEP_DONE message, or the app should not send the new step event from the sync bus message handler, I'm not sure which.

Thread 13 (Thread 0x7ff135534700 (LWP 30991))

  • #0 __lll_lock_wait
    at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S line 135
  • #1 __GI___pthread_mutex_lock
    at ../nptl/pthread_mutex_lock.c line 115
  • #2 gst_element_send_event
    at gstelement.c line 1557
  • #3 do_shuttle
    at playback-test.c line 1559
  • #4 msg_sync_step_done
    at playback-test.c line 1585
  • #5 g_cclosure_marshal_VOID__BOXEDv
    at gmarshal.c line 1160
  • #6 _g_closure_invoke_va
    at gclosure.c line 831
  • #7 g_signal_emit_valist
    at gsignal.c line 3218
  • #8 g_signal_emit
    at gsignal.c line 3365
  • #9 gst_bus_sync_signal_handler
    at gstbus.c line 1197
  • #10 gst_bus_post
    at gstbus.c line 329
  • #11 gst_element_post_message_default
    at gstelement.c line 1688
  • #12 gst_bin_post_message
    at gstbin.c line 2523
  • #13 gst_bin_handle_message_func
    at gstbin.c line 3745
  • #14 gst_pipeline_handle_message
    at gstpipeline.c line 574
  • #15 gst_play_bin_handle_message
    at gstplaybin2.c line 2912
  • #16 bin_bus_handler
    at gstbin.c line 2981
  • #17 gst_bus_post
    at gstbus.c line 323
  • #18 gst_element_post_message_default
    at gstelement.c line 1688
  • #19 gst_bin_post_message
    at gstbin.c line 2523
  • #20 gst_bin_handle_message_func
    at gstbin.c line 3745
  • #21 gst_play_sink_handle_message
    at gstplaysink.c line 4632
  • #22 bin_bus_handler
    at gstbin.c line 2981
  • #23 gst_bus_post
    at gstbus.c line 323
  • #24 gst_element_post_message_default
    at gstelement.c line 1688
  • #25 gst_bin_post_message
    at gstbin.c line 2523
  • #26 gst_bin_handle_message_func
    at gstbin.c line 3745
  • #27 bin_bus_handler
    at gstbin.c line 2981
  • #28 gst_bus_post
    at gstbus.c line 323
  • #29 gst_element_post_message_default
    at gstelement.c line 1688
  • #30 stop_stepping
    at gstbasesink.c line 1694
  • #31 gst_base_sink_chain_unlocked
    at gstbasesink.c line 3457
  • #32 gst_base_sink_chain_main
    at gstbasesink.c line 3547
  • #33 gst_pad_push_data
    at gstpad.c line 3838

Comment 1 Nicolas Dufresne (ndufresne) 2015-10-20 19:10:27 UTC
(Maybe somehow be realated to bug 727949)
Comment 2 Nicolas Dufresne (ndufresne) 2015-10-20 19:11:36 UTC
Created attachment 313771 [details]
Test leading to deaklock

Here's a test program, not exactly the same scenario but the same deadlock point.
Comment 3 Sebastian Dröge (slomo) 2015-10-28 15:40:22 UTC
Can also happen in the following scenario:
1) streaming thread of some element is waiting on a pad probe (stream lock)
2) gst_element_send_event() doing a SEEK, waiting for streaming thread to shut down (state lock -> stream lock)
3) gst_element_set_state() (state lock)

3) *would* unblock the pad, which would unblock the streaming thread and make everything happy... if there wasn't the state lock.
Comment 4 Sebastian Dröge (slomo) 2015-10-28 16:09:52 UTC
Created attachment 314331 [details] [review]
element: Don't hold state lock all the time while sending an event

This can cause various deadlocks, described in
Comment 5 Sebastian Dröge (slomo) 2015-10-28 16:13:15 UTC
Any reason why this is not a good idea? :)
Comment 6 Sebastian Dröge (slomo) 2015-10-29 09:53:03 UTC
It doesn't make gst-validate unhappy in any case.
Comment 7 Sebastian Dröge (slomo) 2015-12-08 16:34:17 UTC
Any comments, ideas, ...? Should we just do this and see what happens? :)

Nobody seems to see a reason why the lock is there at all.
Comment 8 Jan Schmidt 2015-12-09 11:10:53 UTC
I'd guess the intent is to prevent the element from changing state while events are being processed - since state changes may cause unexpected deallocations and things. I think though, that anything that's sensitive to that sort of thing should already be protected with other mechanisms.
Comment 9 Sebastian Dröge (slomo) 2015-12-09 12:07:44 UTC
That might be the reason but protecting for that in this place seems wrong and it should also be protected elsewhere then anyway.

Let's go ahead with this patch then?
Comment 10 Sebastian Dröge (slomo) 2015-12-10 09:38:55 UTC
Attachment 314331 [details] pushed as b427997 - element: Don't hold state lock all the time while sending an event
Comment 11 Sebastian Dröge (slomo) 2015-12-10 09:39:58 UTC
Let's give it a try then, we can still revert it if it is causing other problems.

The commit message now contains further information

commit b427997119a2b6aacbeb550f729936f8b963e24b
Author: Sebastian Dröge <sebastian@centricular.com>
Date:   Thu Dec 10 11:35:05 2015 +0200

    element: Don't hold state lock all the time while sending an event
    
    This lock seems to exist only to prevent elements from changing states while
    events are being processed. However events are going to be processed
    nonetheless in those elements if sent directly via pads, so protection must
    already be implemented inside the elements for event handling if it is needed.
    
    As such having the lock here is not very useful and is actually causing
    various deadlocks in different situations as described in
    https://bugzilla.gnome.org/show_bug.cgi?id=744040
Comment 12 Sebastian Dröge (slomo) 2016-02-17 14:45:07 UTC
commit a0b3a7f65878a844b1f983441749afdd3512ee54
Author: Sebastian Dröge <sebastian@centricular.com>
Date:   Wed Feb 17 16:41:02 2016 +0200

    Revert "element: Don't hold state lock all the time while sending an event"
    
    This reverts commit b427997119a2b6aacbeb550f729936f8b963e24b.
    
    It breaks things that used to work before, even if the change by itself is
    correct and the previous code is just working around deeper bugs in the async
    state change code. Let's go back to what previously worked and then fix async
    state changes in general.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=760532
Comment 13 GStreamer system administrator 2018-11-03 12:25:15 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/gstreamer/gstreamer/issues/91.