playbin about-to-finish deadlock simultaneously setting state to NULL
Application using playbin and connected to about-to-finish will deadlock if protecting its data with a mutex in this multi-thread scenario when simultaneously setting state to NULL - a user has pressed stop.
So, the application will receive about-to-finish in a gstreamer thread, but it seems as it still holds internal mutex in gstreamer. Another thread, like glib mainloop, is setting state to NULL which will result in waiting on same internal gstreamer mutex. If application then has its own mutex to protect its data, we will have a deadlock.
Should it not be possible to use mutex from within about-to-finish callback? To me it seems as the callback should have released internal mutex before handing over control to application.
Internal gstreamer lock involved in gstpad is GST_PAD_STREAM_LOCK (pad) for thread trying to set NULL state:
#2 0x00007ffff7d73cb8 in post_activate (new_mode=GST_PAD_MODE_NONE, pad=0x5555556769e0) at ../gst/gstpad.c:1046
As far as I can see, same pad is used from about-to-finish signal:
#25 0x00007ffff7d74fee in gst_pad_forward (pad=pad@entry=0x5555556769e0, forward=forward@entry=0x7ffff7d78b20 <event_forward_func>, user_data=user_data@entry=0x7ffff5ee4b80) at ../gst/gstpad.c:3074 #26 0x00007ffff7d750fd in gst_pad_event_default (pad=0x5555556769e0, parent=<optimized out>, event=0x7fffec067d60) at ../gst/gstpad.c:3171 #27 0x00007ffff7d6ed47 in gst_pad_send_event_unchecked (pad=pad@entry=0x5555556769e0, event=event@entry=0x7fffec067d60, type=<optimized out>, type@entry=GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM) at ../gst/gstpad.c:5844
Tested in 1.16 and latest 1.18.1, same behavior.
Kind of simple to trigger in a small application, just add g_idle_add from about-to-finish callback with a function that takes a mutex and tries to set NULL state, and make sure callback waits for it to happen and then take same mutex. test_playbin_deadlock.c