GNOME Bugzilla – Bug 768482
shmsrc: stopping shmsrc after socket failure hangs on READY
Last modified: 2016-07-10 22:02:59 UTC
I have a bin that contains shmsrc and capsfilter. I intercept messages in the bin by overriding handle_message. If socket from which shmsrc reads is unexpectedly closed I receive an error message in handle_message sent from streaming thread. I initiate procedure to remove such bin from the pipeline. I set state to NULL, and it never reaches NULL. This is the log with loglevel *:4 0:00:05.322485951 11568 0x20118f0 INFO GST_STATES gstbin.c:2316:gst_bin_element_set_state:<capsfilter> current PLAYING pending VOID_PENDING, desired next PAUSED 0:00:05.322575249 11568 0x20118f0 INFO GST_STATES gstelement.c:2372:gst_element_continue_state:<capsfilter> completed state change to PAUSED 0:00:05.322586658 11568 0x20118f0 INFO GST_STATES gstelement.c:2277:_priv_gst_element_state_changed:<capsfilter> notifying about state-changed PLAYING to PAUSED (VOID_PENDING pending) 0:00:05.322602931 11568 0x20118f0 INFO GST_STATES gstbin.c:2764:gst_bin_change_state_func:<Media.Input.Stream.Test-123> child 'capsfilter' changed state to 3(PAUSED) successfully 0:00:05.322677682 11568 0x20118f0 INFO GST_STATES gstbin.c:2316:gst_bin_element_set_state:<source> current PLAYING pending VOID_PENDING, desired next PAUSED 0:00:05.322724705 11568 0x20118f0 INFO GST_STATES gstelement.c:2372:gst_element_continue_state:<source> completed state change to PAUSED 0:00:05.322734623 11568 0x20118f0 INFO GST_STATES gstelement.c:2277:_priv_gst_element_state_changed:<source> notifying about state-changed PLAYING to PAUSED (VOID_PENDING pending) 0:00:05.322755322 11568 0x20118f0 INFO GST_STATES gstbin.c:2764:gst_bin_change_state_func:<Media.Input.Stream.Test-123> child 'source' changed state to 3(PAUSED) successfully 0:00:05.322774913 11568 0x20118f0 INFO GST_STATES gstelement.c:2347:gst_element_continue_state:<Media.Input.Stream.Test-123> committing state from PLAYING to PAUSED, pending NULL, next READY 0:00:05.322791096 11568 0x20118f0 INFO GST_STATES gstelement.c:2277:_priv_gst_element_state_changed:<Media.Input.Stream.Test-123> notifying about state-changed PLAYING to PAUSED (NULL pending) 0:00:05.322851563 11568 0x20118f0 INFO GST_STATES gstelement.c:2354:gst_element_continue_state:<Media.Input.Stream.Test-123> continue state change PAUSED to READY, final NULL 0:00:05.323275010 11568 0x20118f0 INFO GST_STATES gstbin.c:2316:gst_bin_element_set_state:<capsfilter> current PAUSED pending VOID_PENDING, desired next READY 0:00:05.323350698 11568 0x20118f0 INFO GST_STATES gstelement.c:2372:gst_element_continue_state:<capsfilter> completed state change to READY 0:00:05.323394320 11568 0x20118f0 INFO GST_STATES gstelement.c:2277:_priv_gst_element_state_changed:<capsfilter> notifying about state-changed PAUSED to READY (VOID_PENDING pending) 0:00:05.323412442 11568 0x20118f0 INFO GST_STATES gstbin.c:2764:gst_bin_change_state_func:<Media.Input.Stream.Test-123> child 'capsfilter' changed state to 2(READY) successfully 0:00:05.323424213 11568 0x20118f0 INFO GST_STATES gstbin.c:2316:gst_bin_element_set_state:<source> current PAUSED pending VOID_PENDING, desired next READY
It appears to block the thread. Stack trace: (gdb) thr a a bt
+ Trace 236446
Thread 8 (Thread 0x7f9bf37fe700 (LWP 11831))
Improved stack trace containing glib symbols (gdb) thr a a bt
+ Trace 236447
It seems that with is-live = true it works fine.
I am sorry, it does not work fine with is-live = true. It just hangs at the different stage 0:01:17.668145650 29905 0x7f46c8004320 INFO GST_STATES gstbin.c:2316:gst_bin_element_set_state:<capsfilter> current PLAYING pending VOID_PENDING, desired next PAUSED 0:01:17.668155775 29905 0x7f46c8004320 INFO GST_STATES gstelement.c:2372:gst_element_continue_state:<capsfilter> completed state change to PAUSED 0:01:17.668160619 29905 0x7f46c8004320 INFO GST_STATES gstelement.c:2277:_priv_gst_element_state_changed:<capsfilter> notifying about state-changed PLAYING to PAUSED (VOID_PENDING pending) 0:01:17.668170381 29905 0x7f46c8004320 INFO GST_STATES gstbin.c:2764:gst_bin_change_state_func:<Media.Input.Stream.Test-123> child 'capsfilter' changed state to 3(PAUSED) successfully 0:01:17.668177389 29905 0x7f46c8004320 INFO GST_STATES gstbin.c:2316:gst_bin_element_set_state:<source> current PLAYING pending VOID_PENDING, desired next PAUSED It seems that in both cases it hangs on gst_shm_src_stop_reading (gdb) thr a a bt
+ Trace 236449
Thread 8 (Thread 0x7f1cca7fc700 (LWP 30048))
The error is triggered from within the _create function, with the stream lock taken. You seem to be removing that element from the pipeline directly, which will need the stream lock. The triggering of errors from within the _create function seems OK as other sources (eg, v4l2src) also do this. Maybe the best is to do the pipeline change on a g_idle_add function, which will execute without the lock taken (ie, after the streaming thread has exited from the _create function).
Indeed, you're not allowed to change state on an element from its streaming thread.
Vincent, this is exactly what I ended doing. But then I receive an error multiple times until idle callback is called. It's not something horrible, I just set a flag that ensures that I trigger g_idle_add once per error, it works, just looks more like a workaround than something proper.