deadlock when stop gstreamer

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

deadlock when stop gstreamer

Shuke
Guys,
I had a trouble when try to stop gstreamer . I want to stop playing before
EOF, using gst_element_set_state function. But the call never return, and
deadlock happened.

Pipeline looks like:
.--------------.       .------------------------------------------.
|    playbin   |       |mybin    .------------.     .------------.  |
|----.     .----|       |-----.     | capsfilter |     |  fakesink  |  |
|sink|    |src |---> |ghost|   |----.   .---|      |----.   .---|  |  
handoff
|----'     '----|       |pad  |-->|sink|   |src|-->|sink|   |src|--+-->
handler
|                 |       |-----'      '------------'     '------------'  |
'--------------'       '------------------------------------------'

and bt is:
(gdb) thread apply all bt

Thread 4 (Thread 0x7fb57b1aa700 (LWP 28534)):
#0  0x00007fb58cc0a66d in nanosleep () at /lib64/libc.so.6
#1  0x00007fb58cc3b2f4 in usleep () at /lib64/libc.so.6
#2  0x00007fb58d03b66d in Report::DoReport(void*) ()
    at /usr/local/cvd/sip-user-agent/sip-plugin/build/libsip-plugin.so
#3  0x00007fb586f56070 in  () at /lib64/libstdc++.so.6
#4  0x00007fb58d8a3dc5 in start_thread () at /lib64/libpthread.so.0
#5  0x00007fb58cc4376d in clone () at /lib64/libc.so.6

Thread 3 (Thread 0x7fb568a6b700 (LWP 2929)):
#0  0x00007fb58d8aa1bd in __lll_lock_wait () at /lib64/libpthread.so.0
#1  0x00007fb58d8a5d1d in _L_lock_840 () at /lib64/libpthread.so.0
#2  0x00007fb58d8a5c3a in pthread_mutex_lock () at /lib64/libpthread.so.0
#3  0x00007fb582b1da31 in g_static_rec_mutex_lock () at
/lib64/libglib-2.0.so.0
#4  0x00007fb56bbb90a2 in new_pad () at
/usr/lib64/gstreamer-0.10/libgstdecodebin.so
#5  0x00007fb56bbb91ac in new_caps () at
/usr/lib64/gstreamer-0.10/libgstdecodebin.so
#6  0x00007fb583593ac8 in g_closure_invoke () at /lib64/libgobject-2.0.so.0
#7  0x00007fb5835a616d in signal_emit_unlocked_R () at
/lib64/libgobject-2.0.so.0
#8  0x00007fb5835ae1e1 in g_signal_emit_valist () at
/lib64/libgobject-2.0.so.0
#9  0x00007fb5835ae4cf in g_signal_emit () at /lib64/libgobject-2.0.so.0
#10 0x00007fb5835983a4 in g_object_dispatch_properties_changed () at
/lib64/libgobject-2.0.so.0
#11 0x00007fb5837fcf74 in gst_object_dispatch_properties_changed () at
/lib64/libgstreamer-0.10.so.0
#12 0x00007fb58359a8d9 in g_object_notify_by_pspec () at
/lib64/libgobject-2.0.so.0
#13 0x00007fb58382b8d4 in gst_pad_set_caps () at
/lib64/libgstreamer-0.10.so.0
#14 0x00007fb56af7b4d4 in gst_mpeg_audio_parse_parse_frame () at
/usr/lib64/gstreamer-0.10/libgstaudioparsers.so
#15 0x00007fb5782b9124 in gst_base_parse_handle_and_push_frame.isra.7 () at
/usr/lib64/libgstbase-0.10.so.0
#16 0x00007fb5782bbc43 in gst_base_parse_loop () at
/usr/lib64/libgstbase-0.10.so.0
#17 0x00007fb583856a14 in gst_task_func () at /lib64/libgstreamer-0.10.so.0
#18 0x00007fb582b7230c in g_thread_pool_thread_proxy () at
/lib64/libglib-2.0.so.0
#19 0x00007fb582b71970 in g_thread_proxy () at /lib64/libglib-2.0.so.0
#20 0x00007fb58d8a3dc5 in start_thread () at /lib64/libpthread.so.0
#21 0x00007fb58cc4376d in clone () at /lib64/libc.so.6

Thread 2 (Thread 0x7fb57958e700 (LWP 3324)):
#0  0x00007fb58d8aa1bd in __lll_lock_wait () at /lib64/libpthread.so.0
#1  0x00007fb58d8a5d1d in _L_lock_840 () at /lib64/libpthread.so.0
#2  0x00007fb58d8a5c3a in pthread_mutex_lock () at /lib64/libpthread.so.0
#3  0x00007fb582b1da31 in g_static_rec_mutex_lock () at
/lib64/libglib-2.0.so.0
#4  0x00007fb5782b4825 in gst_base_parse_activate () at
/usr/lib64/libgstbase-0.10.so.0
#5  0x00007fb5782b48df in gst_base_parse_sink_activate_pull () at
/usr/lib64/libgstbase-0.10.so.0
#6  0x00007fb58382f401 in gst_pad_activate_pull () at
/lib64/libgstreamer-0.10.so.0
#7  0x00007fb58382ff37 in gst_pad_set_active () at
/lib64/libgstreamer-0.10.so.0
#8  0x00007fb583811f21 in activate_pads () at /lib64/libgstreamer-0.10.so.0
#9  0x00007fb58382325d in gst_iterator_fold () at
/lib64/libgstreamer-0.10.so.0
#10 0x00007fb583811fab in iterator_activate_fold_with_resync () at
/lib64/libgstreamer-0.10.so.0
#11 0x00007fb58381459d in gst_element_pads_activate () at
/lib64/libgstreamer-0.10.so.0
#12 0x00007fb583814874 in gst_element_change_state_func () at
/lib64/libgstreamer-0.10.so.0
#13 0x00007fb5782b571d in gst_base_parse_change_state () at
/usr/lib64/libgstbase-0.10.so.0
#14 0x00007fb5838163b2 in gst_element_change_state () at
/lib64/libgstreamer-0.10.so.0
#15 0x00007fb583816a23 in gst_element_set_state_func () at
/lib64/libgstreamer-0.10.so.0
#16 0x00007fb583804412 in gst_bin_change_state_func () at
/lib64/libgstreamer-0.10.so.0
#17 0x00007fb56bbb7441 in gst_decode_bin_change_state () at
/usr/lib64/gstreamer-0.10/libgstdecodebin.so
#18 0x00007fb5838163b2 in gst_element_change_state () at
/lib64/libgstreamer-0.10.so.0
#19 0x00007fb583816a23 in gst_element_set_state_func () at
/lib64/libgstreamer-0.10.so.0
#20 0x00007fb583804412 in gst_bin_change_state_func () at
/lib64/libgstreamer-0.10.so.0
#21 0x00007fb583834552 in gst_pipeline_change_state () at
/lib64/libgstreamer-0.10.so.0
#22 0x00007fb578b6e8fd in gst_play_base_bin_change_state () at
/usr/lib64/gstreamer-0.10/libgstplaybin.so
#23 0x00007fb578b55665 in gst_play_bin_change_state () at
/usr/lib64/gstreamer-0.10/libgstplaybin.so
#24 0x00007fb5838163b2 in gst_element_change_state () at
/lib64/libgstreamer-0.10.so.0
#25 0x00007fb583816a23 in gst_element_set_state_func () at
/lib64/libgstreamer-0.10.so.0
#26 0x00007fb583804412 in gst_bin_change_state_func () at
/lib64/libgstreamer-0.10.so.0
#27 0x00007fb583834552 in gst_pipeline_change_state () at
/lib64/libgstreamer-0.10.so.0
#28 0x00007fb5838163b2 in gst_element_change_state () at
/lib64/libgstreamer-0.10.so.0
#29 0x00007fb583816a23 in gst_element_set_state_func () at
/lib64/libgstreamer-0.10.so.0
#30 0x00007fb583abfd6e in thread (arg=0x1765e7e0) at modules/gst/gst.c:93
#31 0x00007fb58d8a3dc5 in start_thread () at /lib64/libpthread.so.0
#32 0x00007fb58cc4376d in clone () at /lib64/libc.so.6

Thread 1 (Thread 0x7fb58ea12980 (LWP 28516)):
#0  0x00007fb58d8a4ef7 in pthread_join () at /lib64/libpthread.so.0
#1  0x00007fb583abfdc7 in gst_destructor (arg=0x1765e7e0) at
modules/gst/gst.c:423
#2  0x00007fb58e5f54ba in mem_deref (data=0x1765e7e0) at src/mem/mem.c:318
#3  0x000000000040ee95 in audio_set_source (au=au@entry=0x17508140,
mod=mod@entry=0x7ffe4ab103d0 "gst", device=device@entry=0x7ffe4ab103e0
"file:///usr/local/cvd/sip-user-agent/baresip/baresip-0.5.9/empty.mp3")
    at src/audio.c:2083
#4  0x00007fb57b1acc30 in switch_audio_device
(session_id=session_id@entry=0x1057f108 "2d3da0e4ddd9fd1f",
device=device@entry=0x0) at modules/robot/robot.c:162
#5  0x00007fb57b1ace0b in switch_audio_device (session_id=0x1057f108
"2d3da0e4ddd9fd1f", device=0x0)
    at modules/robot/robot.c:182
#6  0x00007fb58d0417ac in PlayCmd::Action() () at
/usr/local/cvd/sip-user-agent/sip-plugin/build/libsip-plugin.so
#7  0x00007fb58d040367 in TimerProcess() () at
/usr/local/cvd/sip-user-agent/sip-plugin/build/libsip-plugin.so
#8  0x00007fb57b1ac7a9 in plugin_timer_handler (arg=arg@entry=0x0) at
modules/robot/robot.c:238
#9  0x00007fb58e5f389c in tmr_poll (tmrl=tmrl@entry=0x7fb58e815880
<global_re+32>) at src/tmr/tmr.c:113
#10 0x00007fb58e5f4ce8 in re_main (signalh=signalh@entry=0x421c30
<signal_handler>) at src/main/main.c:994
#11 0x000000000040a356 in main (argc=<optimized out>, argv=<optimized out>)
at src/main.c:242

Thanks a lot.



--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: deadlock when stop gstreamer

Michael Gruner
Hi

Can you share the source code? Or at least a minimal example that is able to reproduce this issue?

Michael

> On Jan 12, 2019, at 7:36 AM, Shuke <[hidden email]> wrote:
>
> Guys,
> I had a trouble when try to stop gstreamer . I want to stop playing before
> EOF, using gst_element_set_state function. But the call never return, and
> deadlock happened.
>
> Pipeline looks like:
> .--------------.       .------------------------------------------.
> |    playbin   |       |mybin    .------------.     .------------.  |
> |----.     .----|       |-----.     | capsfilter |     |  fakesink  |  |
> |sink|    |src |---> |ghost|   |----.   .---|      |----.   .---|  |  
> handoff
> |----'     '----|       |pad  |-->|sink|   |src|-->|sink|   |src|--+-->
> handler
> |                 |       |-----'      '------------'     '------------'  |
> '--------------'       '------------------------------------------'
>
> and bt is:
> (gdb) thread apply all bt
>
> Thread 4 (Thread 0x7fb57b1aa700 (LWP 28534)):
> #0  0x00007fb58cc0a66d in nanosleep () at /lib64/libc.so.6
> #1  0x00007fb58cc3b2f4 in usleep () at /lib64/libc.so.6
> #2  0x00007fb58d03b66d in Report::DoReport(void*) ()
>    at /usr/local/cvd/sip-user-agent/sip-plugin/build/libsip-plugin.so
> #3  0x00007fb586f56070 in  () at /lib64/libstdc++.so.6
> #4  0x00007fb58d8a3dc5 in start_thread () at /lib64/libpthread.so.0
> #5  0x00007fb58cc4376d in clone () at /lib64/libc.so.6
>
> Thread 3 (Thread 0x7fb568a6b700 (LWP 2929)):
> #0  0x00007fb58d8aa1bd in __lll_lock_wait () at /lib64/libpthread.so.0
> #1  0x00007fb58d8a5d1d in _L_lock_840 () at /lib64/libpthread.so.0
> #2  0x00007fb58d8a5c3a in pthread_mutex_lock () at /lib64/libpthread.so.0
> #3  0x00007fb582b1da31 in g_static_rec_mutex_lock () at
> /lib64/libglib-2.0.so.0
> #4  0x00007fb56bbb90a2 in new_pad () at
> /usr/lib64/gstreamer-0.10/libgstdecodebin.so
> #5  0x00007fb56bbb91ac in new_caps () at
> /usr/lib64/gstreamer-0.10/libgstdecodebin.so
> #6  0x00007fb583593ac8 in g_closure_invoke () at /lib64/libgobject-2.0.so.0
> #7  0x00007fb5835a616d in signal_emit_unlocked_R () at
> /lib64/libgobject-2.0.so.0
> #8  0x00007fb5835ae1e1 in g_signal_emit_valist () at
> /lib64/libgobject-2.0.so.0
> #9  0x00007fb5835ae4cf in g_signal_emit () at /lib64/libgobject-2.0.so.0
> #10 0x00007fb5835983a4 in g_object_dispatch_properties_changed () at
> /lib64/libgobject-2.0.so.0
> #11 0x00007fb5837fcf74 in gst_object_dispatch_properties_changed () at
> /lib64/libgstreamer-0.10.so.0
> #12 0x00007fb58359a8d9 in g_object_notify_by_pspec () at
> /lib64/libgobject-2.0.so.0
> #13 0x00007fb58382b8d4 in gst_pad_set_caps () at
> /lib64/libgstreamer-0.10.so.0
> #14 0x00007fb56af7b4d4 in gst_mpeg_audio_parse_parse_frame () at
> /usr/lib64/gstreamer-0.10/libgstaudioparsers.so
> #15 0x00007fb5782b9124 in gst_base_parse_handle_and_push_frame.isra.7 () at
> /usr/lib64/libgstbase-0.10.so.0
> #16 0x00007fb5782bbc43 in gst_base_parse_loop () at
> /usr/lib64/libgstbase-0.10.so.0
> #17 0x00007fb583856a14 in gst_task_func () at /lib64/libgstreamer-0.10.so.0
> #18 0x00007fb582b7230c in g_thread_pool_thread_proxy () at
> /lib64/libglib-2.0.so.0
> #19 0x00007fb582b71970 in g_thread_proxy () at /lib64/libglib-2.0.so.0
> #20 0x00007fb58d8a3dc5 in start_thread () at /lib64/libpthread.so.0
> #21 0x00007fb58cc4376d in clone () at /lib64/libc.so.6
>
> Thread 2 (Thread 0x7fb57958e700 (LWP 3324)):
> #0  0x00007fb58d8aa1bd in __lll_lock_wait () at /lib64/libpthread.so.0
> #1  0x00007fb58d8a5d1d in _L_lock_840 () at /lib64/libpthread.so.0
> #2  0x00007fb58d8a5c3a in pthread_mutex_lock () at /lib64/libpthread.so.0
> #3  0x00007fb582b1da31 in g_static_rec_mutex_lock () at
> /lib64/libglib-2.0.so.0
> #4  0x00007fb5782b4825 in gst_base_parse_activate () at
> /usr/lib64/libgstbase-0.10.so.0
> #5  0x00007fb5782b48df in gst_base_parse_sink_activate_pull () at
> /usr/lib64/libgstbase-0.10.so.0
> #6  0x00007fb58382f401 in gst_pad_activate_pull () at
> /lib64/libgstreamer-0.10.so.0
> #7  0x00007fb58382ff37 in gst_pad_set_active () at
> /lib64/libgstreamer-0.10.so.0
> #8  0x00007fb583811f21 in activate_pads () at /lib64/libgstreamer-0.10.so.0
> #9  0x00007fb58382325d in gst_iterator_fold () at
> /lib64/libgstreamer-0.10.so.0
> #10 0x00007fb583811fab in iterator_activate_fold_with_resync () at
> /lib64/libgstreamer-0.10.so.0
> #11 0x00007fb58381459d in gst_element_pads_activate () at
> /lib64/libgstreamer-0.10.so.0
> #12 0x00007fb583814874 in gst_element_change_state_func () at
> /lib64/libgstreamer-0.10.so.0
> #13 0x00007fb5782b571d in gst_base_parse_change_state () at
> /usr/lib64/libgstbase-0.10.so.0
> #14 0x00007fb5838163b2 in gst_element_change_state () at
> /lib64/libgstreamer-0.10.so.0
> #15 0x00007fb583816a23 in gst_element_set_state_func () at
> /lib64/libgstreamer-0.10.so.0
> #16 0x00007fb583804412 in gst_bin_change_state_func () at
> /lib64/libgstreamer-0.10.so.0
> #17 0x00007fb56bbb7441 in gst_decode_bin_change_state () at
> /usr/lib64/gstreamer-0.10/libgstdecodebin.so
> #18 0x00007fb5838163b2 in gst_element_change_state () at
> /lib64/libgstreamer-0.10.so.0
> #19 0x00007fb583816a23 in gst_element_set_state_func () at
> /lib64/libgstreamer-0.10.so.0
> #20 0x00007fb583804412 in gst_bin_change_state_func () at
> /lib64/libgstreamer-0.10.so.0
> #21 0x00007fb583834552 in gst_pipeline_change_state () at
> /lib64/libgstreamer-0.10.so.0
> #22 0x00007fb578b6e8fd in gst_play_base_bin_change_state () at
> /usr/lib64/gstreamer-0.10/libgstplaybin.so
> #23 0x00007fb578b55665 in gst_play_bin_change_state () at
> /usr/lib64/gstreamer-0.10/libgstplaybin.so
> #24 0x00007fb5838163b2 in gst_element_change_state () at
> /lib64/libgstreamer-0.10.so.0
> #25 0x00007fb583816a23 in gst_element_set_state_func () at
> /lib64/libgstreamer-0.10.so.0
> #26 0x00007fb583804412 in gst_bin_change_state_func () at
> /lib64/libgstreamer-0.10.so.0
> #27 0x00007fb583834552 in gst_pipeline_change_state () at
> /lib64/libgstreamer-0.10.so.0
> #28 0x00007fb5838163b2 in gst_element_change_state () at
> /lib64/libgstreamer-0.10.so.0
> #29 0x00007fb583816a23 in gst_element_set_state_func () at
> /lib64/libgstreamer-0.10.so.0
> #30 0x00007fb583abfd6e in thread (arg=0x1765e7e0) at modules/gst/gst.c:93
> #31 0x00007fb58d8a3dc5 in start_thread () at /lib64/libpthread.so.0
> #32 0x00007fb58cc4376d in clone () at /lib64/libc.so.6
>
> Thread 1 (Thread 0x7fb58ea12980 (LWP 28516)):
> #0  0x00007fb58d8a4ef7 in pthread_join () at /lib64/libpthread.so.0
> #1  0x00007fb583abfdc7 in gst_destructor (arg=0x1765e7e0) at
> modules/gst/gst.c:423
> #2  0x00007fb58e5f54ba in mem_deref (data=0x1765e7e0) at src/mem/mem.c:318
> #3  0x000000000040ee95 in audio_set_source (au=au@entry=0x17508140,
> mod=mod@entry=0x7ffe4ab103d0 "gst", device=device@entry=0x7ffe4ab103e0
> "file:///usr/local/cvd/sip-user-agent/baresip/baresip-0.5.9/empty.mp3")
>    at src/audio.c:2083
> #4  0x00007fb57b1acc30 in switch_audio_device
> (session_id=session_id@entry=0x1057f108 "2d3da0e4ddd9fd1f",
> device=device@entry=0x0) at modules/robot/robot.c:162
> #5  0x00007fb57b1ace0b in switch_audio_device (session_id=0x1057f108
> "2d3da0e4ddd9fd1f", device=0x0)
>    at modules/robot/robot.c:182
> #6  0x00007fb58d0417ac in PlayCmd::Action() () at
> /usr/local/cvd/sip-user-agent/sip-plugin/build/libsip-plugin.so
> #7  0x00007fb58d040367 in TimerProcess() () at
> /usr/local/cvd/sip-user-agent/sip-plugin/build/libsip-plugin.so
> #8  0x00007fb57b1ac7a9 in plugin_timer_handler (arg=arg@entry=0x0) at
> modules/robot/robot.c:238
> #9  0x00007fb58e5f389c in tmr_poll (tmrl=tmrl@entry=0x7fb58e815880
> <global_re+32>) at src/tmr/tmr.c:113
> #10 0x00007fb58e5f4ce8 in re_main (signalh=signalh@entry=0x421c30
> <signal_handler>) at src/main/main.c:994
> #11 0x000000000040a356 in main (argc=<optimized out>, argv=<optimized out>)
> at src/main.c:242
>
> Thanks a lot.
>
>
>
> --
> Sent from: http://gstreamer-devel.966125.n4.nabble.com/
> _______________________________________________
> gstreamer-devel mailing list
> [hidden email]
> https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: deadlock when stop gstreamer

Shuke
Hi Gruner:

The source code is pasted below, and in the attachment. We use gst_alloc to create a gstreamer, and call gst_destructor to stop gstreamer from playing, bofore EOF was reached.

Please tell us if we had a bad use, or something bad was triggered.

Thanks.


struct ausrc_st {
const struct ausrc *as;     /**< Inheritance             */

pthread_t tid;              /**< Thread ID               */
bool run;                   /**< Running flag            */
   
    ...

/* Gstreamer */
char *uri;
GstElement *pipeline, *bin, *source, *capsfilt, *sink;
GMainLoop *loop;
};

static void *thread(void *arg)
{
struct ausrc_st *st = arg;
gst_element_set_state(st->pipeline, GST_STATE_PLAYING);

while (st->run) {
g_main_loop_run(st->loop);
}

//deadlock will happen in this line
gst_element_set_state(st->pipeline, GST_STATE_NULL);
return NULL;
}


static gboolean bus_watch_handler(GstBus *bus, GstMessage *msg, gpointer data)
{
struct ausrc_st *st = data;
GMainLoop *loop = st->loop;
(void)bus;
switch (GST_MESSAGE_TYPE(msg)) {

case GST_MESSAGE_EOS:

break;

case GST_MESSAGE_ERROR:
st->run = false;
g_main_loop_quit(loop);
break;
default:
break;
}

return TRUE;
}


static void handoff_handler(GstFakeSink *fakesink, GstBuffer *buffer,
                            GstPad *pad, gpointer user_data)
{
struct ausrc_st *st = user_data;

(void)fakesink;
(void)pad;

// ... get data from buffer and sleep.
}

/**
 * Set up the Gstreamer pipeline. The playbin element is used to decode
 * all kinds of different formats. The capsfilter is used to deliver the
 * audio in a fixed format (X Hz, 1-2 channels, 16 bit signed)
 *
 * The pipeline looks like this:
 *
 * <pre>
 *  .--------------.    .------------------------------------------.
 *  |    playbin   |    |mybin    .------------.   .------------.  |
 *  |----.    .----|    |-----.   | capsfilter |   |  fakesink  |  |
 *  |sink|    |src |--->|ghost|   |----.   .---|   |----.   .---|  |    handoff
 *  |----'    '----|    |pad  |-->|sink|   |src|-->|sink|   |src|--+--> handler
 *  |              |    |-----'   '------------'   '------------'  |
 *  '--------------'    '------------------------------------------'
 * </pre>
 *
 * @param st Audio source state
 *
 * @return 0 if success, otherwise errorcode
 */

static int gst_setup(struct ausrc_st *st)
{
GstBus *bus;
GstPad *pad;

st->loop = g_main_loop_new(NULL, FALSE);

st->pipeline = gst_pipeline_new("pipeline");
if (!st->pipeline) {
warning("gst: failed to create pipeline element\n");
return ENOMEM;
}

/********************* Player BIN **************************/

st->source = gst_element_factory_make("playbin", "source");
if (!st->source) {
warning("gst: failed to create playbin source element\n");
return ENOMEM;
}

/********************* My BIN **************************/

st->bin = gst_bin_new("mybin");

st->capsfilt = gst_element_factory_make("capsfilter", NULL);
if (!st->capsfilt) {
warning("gst: failed to create capsfilter element\n");
return ENOMEM;
}

set_caps(st);

st->sink = gst_element_factory_make("fakesink", "sink");
if (!st->sink) {
warning("gst: failed to create sink element\n");
return ENOMEM;
}

gst_bin_add_many(GST_BIN(st->bin), st->capsfilt, st->sink, NULL);
gst_element_link_many(st->capsfilt, st->sink, NULL);

/* add ghostpad */
pad = gst_element_get_pad(st->capsfilt, "sink");
gst_element_add_pad(st->bin, gst_ghost_pad_new("sink", pad));
gst_object_unref(GST_OBJECT(pad));

/* put all elements in a bin */
gst_bin_add_many(GST_BIN(st->pipeline), st->source, NULL);

/* Override audio-sink handoff handler */
g_object_set(G_OBJECT(st->sink), "signal-handoffs", TRUE, NULL);
g_signal_connect(st->sink, "handoff", G_CALLBACK(handoff_handler), st);
g_object_set(G_OBJECT(st->source), "audio-sink", st->bin, NULL);

/********************* Misc **************************/

/* Bus watch */
bus = gst_pipeline_get_bus(GST_PIPELINE(st->pipeline));
gst_bus_add_watch(bus, bus_watch_handler, st);
gst_object_unref(bus);

/* Set URI */
g_object_set(G_OBJECT(st->source), "uri", st->uri, NULL);

return 0;
}



static void gst_destructor(void *arg)
{
struct ausrc_st *st = arg;
int err = 0;
if (st->run) {
st->run = false;
g_main_loop_quit(st->loop);
err = pthread_join(st->tid, NULL);
}
//deadlock will happen in this line
gst_element_set_state(st->pipeline, GST_STATE_NULL);
gst_object_unref(GST_OBJECT(st->pipeline));
mem_deref(st->call_id);
mem_deref(st->uri);
mem_deref(st->aubuf);
}


static int gst_alloc(struct ausrc_st **stp, const struct ausrc *as,
                     struct media_ctx **ctx,
                     struct ausrc_prm *prm, const char *device, const char *call_id,
                     ausrc_read_h *rh, ausrc_error_h *errh, void *arg)
{
struct ausrc_st *st;
int err;
(void)ctx;
err = gst_setup(st);
if (err)
goto out;

st->run  = true;
err = pthread_create(&st->tid, NULL, thread, st);
if (err) {
st->run = false;
goto out;
}

out:
if (err)
mem_deref(st);
else
*stp = st;

return err;
}


------------------ Original ------------------
From:  "Michael Gruner"<[hidden email]>;
Date:  Tue, Jan 15, 2019 07:20 AM
To:  "舒科"<[hidden email]>;"Discussion of the development of and with GStreamer"<[hidden email]>;
Subject:  Re: deadlock when stop gstreamer

Hi

Can you share the source code? Or at least a minimal example that is able to reproduce this issue?

Michael

> On Jan 12, 2019, at 7:36 AM, Shuke <[hidden email]> wrote:
>
> Guys,
> I had a trouble when try to stop gstreamer . I want to stop playing before
> EOF, using gst_element_set_state function. But the call never return, and
> deadlock happened.
>
> Pipeline looks like:
> .--------------.       .------------------------------------------.
> |    playbin   |       |mybin    .------------.     .------------.  |
> |----.     .----|       |-----.     | capsfilter |     |  fakesink  |  |
> |sink|    |src |---> |ghost|   |----.   .---|      |----.   .---|  |  
> handoff
> |----'     '----|       |pad  |-->|sink|   |src|-->|sink|   |src|--+-->
> handler
> |                 |       |-----'      '------------'     '------------'  |
> '--------------'       '------------------------------------------'
>
> and bt is:
> (gdb) thread apply all bt
>
> Thread 4 (Thread 0x7fb57b1aa700 (LWP 28534)):
> #0  0x00007fb58cc0a66d in nanosleep () at /lib64/libc.so.6
> #1  0x00007fb58cc3b2f4 in usleep () at /lib64/libc.so.6
> #2  0x00007fb58d03b66d in Report::DoReport(void*) ()
>    at /usr/local/cvd/sip-user-agent/sip-plugin/build/libsip-plugin.so
> #3  0x00007fb586f56070 in  () at /lib64/libstdc++.so.6
> #4  0x00007fb58d8a3dc5 in start_thread () at /lib64/libpthread.so.0
> #5  0x00007fb58cc4376d in clone () at /lib64/libc.so.6
>
> Thread 3 (Thread 0x7fb568a6b700 (LWP 2929)):
> #0  0x00007fb58d8aa1bd in __lll_lock_wait () at /lib64/libpthread.so.0
> #1  0x00007fb58d8a5d1d in _L_lock_840 () at /lib64/libpthread.so.0
> #2  0x00007fb58d8a5c3a in pthread_mutex_lock () at /lib64/libpthread.so.0
> #3  0x00007fb582b1da31 in g_static_rec_mutex_lock () at
> /lib64/libglib-2.0.so.0
> #4  0x00007fb56bbb90a2 in new_pad () at
> /usr/lib64/gstreamer-0.10/libgstdecodebin.so
> #5  0x00007fb56bbb91ac in new_caps () at
> /usr/lib64/gstreamer-0.10/libgstdecodebin.so
> #6  0x00007fb583593ac8 in g_closure_invoke () at /lib64/libgobject-2.0.so.0
> #7  0x00007fb5835a616d in signal_emit_unlocked_R () at
> /lib64/libgobject-2.0.so.0
> #8  0x00007fb5835ae1e1 in g_signal_emit_valist () at
> /lib64/libgobject-2.0.so.0
> #9  0x00007fb5835ae4cf in g_signal_emit () at /lib64/libgobject-2.0.so.0
> #10 0x00007fb5835983a4 in g_object_dispatch_properties_changed () at
> /lib64/libgobject-2.0.so.0
> #11 0x00007fb5837fcf74 in gst_object_dispatch_properties_changed () at
> /lib64/libgstreamer-0.10.so.0
> #12 0x00007fb58359a8d9 in g_object_notify_by_pspec () at
> /lib64/libgobject-2.0.so.0
> #13 0x00007fb58382b8d4 in gst_pad_set_caps () at
> /lib64/libgstreamer-0.10.so.0
> #14 0x00007fb56af7b4d4 in gst_mpeg_audio_parse_parse_frame () at
> /usr/lib64/gstreamer-0.10/libgstaudioparsers.so
> #15 0x00007fb5782b9124 in gst_base_parse_handle_and_push_frame.isra.7 () at
> /usr/lib64/libgstbase-0.10.so.0
> #16 0x00007fb5782bbc43 in gst_base_parse_loop () at
> /usr/lib64/libgstbase-0.10.so.0
> #17 0x00007fb583856a14 in gst_task_func () at /lib64/libgstreamer-0.10.so.0
> #18 0x00007fb582b7230c in g_thread_pool_thread_proxy () at
> /lib64/libglib-2.0.so.0
> #19 0x00007fb582b71970 in g_thread_proxy () at /lib64/libglib-2.0.so.0
> #20 0x00007fb58d8a3dc5 in start_thread () at /lib64/libpthread.so.0
> #21 0x00007fb58cc4376d in clone () at /lib64/libc.so.6
>
> Thread 2 (Thread 0x7fb57958e700 (LWP 3324)):
> #0  0x00007fb58d8aa1bd in __lll_lock_wait () at /lib64/libpthread.so.0
> #1  0x00007fb58d8a5d1d in _L_lock_840 () at /lib64/libpthread.so.0
> #2  0x00007fb58d8a5c3a in pthread_mutex_lock () at /lib64/libpthread.so.0
> #3  0x00007fb582b1da31 in g_static_rec_mutex_lock () at
> /lib64/libglib-2.0.so.0
> #4  0x00007fb5782b4825 in gst_base_parse_activate () at
> /usr/lib64/libgstbase-0.10.so.0
> #5  0x00007fb5782b48df in gst_base_parse_sink_activate_pull () at
> /usr/lib64/libgstbase-0.10.so.0
> #6  0x00007fb58382f401 in gst_pad_activate_pull () at
> /lib64/libgstreamer-0.10.so.0
> #7  0x00007fb58382ff37 in gst_pad_set_active () at
> /lib64/libgstreamer-0.10.so.0
> #8  0x00007fb583811f21 in activate_pads () at /lib64/libgstreamer-0.10.so.0
> #9  0x00007fb58382325d in gst_iterator_fold () at
> /lib64/libgstreamer-0.10.so.0
> #10 0x00007fb583811fab in iterator_activate_fold_with_resync () at
> /lib64/libgstreamer-0.10.so.0
> #11 0x00007fb58381459d in gst_element_pads_activate () at
> /lib64/libgstreamer-0.10.so.0
> #12 0x00007fb583814874 in gst_element_change_state_func () at
> /lib64/libgstreamer-0.10.so.0
> #13 0x00007fb5782b571d in gst_base_parse_change_state () at
> /usr/lib64/libgstbase-0.10.so.0
> #14 0x00007fb5838163b2 in gst_element_change_state () at
> /lib64/libgstreamer-0.10.so.0
> #15 0x00007fb583816a23 in gst_element_set_state_func () at
> /lib64/libgstreamer-0.10.so.0
> #16 0x00007fb583804412 in gst_bin_change_state_func () at
> /lib64/libgstreamer-0.10.so.0
> #17 0x00007fb56bbb7441 in gst_decode_bin_change_state () at
> /usr/lib64/gstreamer-0.10/libgstdecodebin.so
> #18 0x00007fb5838163b2 in gst_element_change_state () at
> /lib64/libgstreamer-0.10.so.0
> #19 0x00007fb583816a23 in gst_element_set_state_func () at
> /lib64/libgstreamer-0.10.so.0
> #20 0x00007fb583804412 in gst_bin_change_state_func () at
> /lib64/libgstreamer-0.10.so.0
> #21 0x00007fb583834552 in gst_pipeline_change_state () at
> /lib64/libgstreamer-0.10.so.0
> #22 0x00007fb578b6e8fd in gst_play_base_bin_change_state () at
> /usr/lib64/gstreamer-0.10/libgstplaybin.so
> #23 0x00007fb578b55665 in gst_play_bin_change_state () at
> /usr/lib64/gstreamer-0.10/libgstplaybin.so
> #24 0x00007fb5838163b2 in gst_element_change_state () at
> /lib64/libgstreamer-0.10.so.0
> #25 0x00007fb583816a23 in gst_element_set_state_func () at
> /lib64/libgstreamer-0.10.so.0
> #26 0x00007fb583804412 in gst_bin_change_state_func () at
> /lib64/libgstreamer-0.10.so.0
> #27 0x00007fb583834552 in gst_pipeline_change_state () at
> /lib64/libgstreamer-0.10.so.0
> #28 0x00007fb5838163b2 in gst_element_change_state () at
> /lib64/libgstreamer-0.10.so.0
> #29 0x00007fb583816a23 in gst_element_set_state_func () at
> /lib64/libgstreamer-0.10.so.0
> #30 0x00007fb583abfd6e in thread (arg=0x1765e7e0) at modules/gst/gst.c:93
> #31 0x00007fb58d8a3dc5 in start_thread () at /lib64/libpthread.so.0
> #32 0x00007fb58cc4376d in clone () at /lib64/libc.so.6
>
> Thread 1 (Thread 0x7fb58ea12980 (LWP 28516)):
> #0  0x00007fb58d8a4ef7 in pthread_join () at /lib64/libpthread.so.0
> #1  0x00007fb583abfdc7 in gst_destructor (arg=0x1765e7e0) at
> modules/gst/gst.c:423
> #2  0x00007fb58e5f54ba in mem_deref (data=0x1765e7e0) at src/mem/mem.c:318
> #3  0x000000000040ee95 in audio_set_source (au=au@entry=0x17508140,
> mod=mod@entry=0x7ffe4ab103d0 "gst", device=device@entry=0x7ffe4ab103e0
> "file:///usr/local/cvd/sip-user-agent/baresip/baresip-0.5.9/empty.mp3")
>    at src/audio.c:2083
> #4  0x00007fb57b1acc30 in switch_audio_device
> (session_id=session_id@entry=0x1057f108 "2d3da0e4ddd9fd1f",
> device=device@entry=0x0) at modules/robot/robot.c:162
> #5  0x00007fb57b1ace0b in switch_audio_device (session_id=0x1057f108
> "2d3da0e4ddd9fd1f", device=0x0)
>    at modules/robot/robot.c:182
> #6  0x00007fb58d0417ac in PlayCmd::Action() () at
> /usr/local/cvd/sip-user-agent/sip-plugin/build/libsip-plugin.so
> #7  0x00007fb58d040367 in TimerProcess() () at
> /usr/local/cvd/sip-user-agent/sip-plugin/build/libsip-plugin.so
> #8  0x00007fb57b1ac7a9 in plugin_timer_handler (arg=arg@entry=0x0) at
> modules/robot/robot.c:238
> #9  0x00007fb58e5f389c in tmr_poll (tmrl=tmrl@entry=0x7fb58e815880
> <global_re+32>) at src/tmr/tmr.c:113
> #10 0x00007fb58e5f4ce8 in re_main (signalh=signalh@entry=0x421c30
> <signal_handler>) at src/main/main.c:994
> #11 0x000000000040a356 in main (argc=<optimized out>, argv=<optimized out>)
> at src/main.c:242
>
> Thanks a lot.
>
>
>
> --
> Sent from: http://gstreamer-devel.966125.n4.nabble.com/
> _______________________________________________
> gstreamer-devel mailing list
> [hidden email]
> https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel


_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: deadlock when stop gstreamer

Shuke
In reply to this post by Shuke
We call gst_alloc to start a gstreamer, which will create another thread to
do the main loop. And before EOF was retrieved, we'll call gst_destructor to
tell main loop to quit, which will call gst_element_set_state, which cause
deadlock with pipeline thread.

Deadlock is not always occurs, it occurs once in thousands.

Thanks a lot.


Source code is pasted below.


struct ausrc_st {
        const struct ausrc *as;     /**< Inheritance             */

        pthread_t tid;              /**< Thread ID               */
        bool run;                   /**< Running flag            */
   
    ...

        /* Gstreamer */
        char *uri;
        GstElement *pipeline, *bin, *source, *capsfilt, *sink;
        GMainLoop *loop;
};

static void *thread(void *arg)
{
        struct ausrc_st *st = arg;
        gst_element_set_state(st->pipeline, GST_STATE_PLAYING);

        while (st->run) {
                g_main_loop_run(st->loop);
        }

        //deadlock will happen in this line
        gst_element_set_state(st->pipeline, GST_STATE_NULL);
        return NULL;
}


static gboolean bus_watch_handler(GstBus *bus, GstMessage *msg, gpointer
data)
{
        struct ausrc_st *st = data;
        GMainLoop *loop = st->loop;
        (void)bus;
        switch (GST_MESSAGE_TYPE(msg)) {

        case GST_MESSAGE_EOS:

                break;

        case GST_MESSAGE_ERROR:
                st->run = false;
                g_main_loop_quit(loop);
                break;
        default:
                break;
        }

        return TRUE;
}


static void handoff_handler(GstFakeSink *fakesink, GstBuffer *buffer,
                            GstPad *pad, gpointer user_data)
{
        struct ausrc_st *st = user_data;

        (void)fakesink;
        (void)pad;

        // ... get data from buffer and sleep.
}

/**
 * Set up the Gstreamer pipeline. The playbin element is used to decode
 * all kinds of different formats. The capsfilter is used to deliver the
 * audio in a fixed format (X Hz, 1-2 channels, 16 bit signed)
 *
 * The pipeline looks like this:
 *
 * <pre>
 *  .--------------.    .------------------------------------------.
 *  |    playbin   |    |mybin    .------------.   .------------.  |
 *  |----.    .----|    |-----.   | capsfilter |   |  fakesink  |  |
 *  |sink|    |src |--->|ghost|   |----.   .---|   |----.   .---|  |  
handoff
 *  |----'    '----|    |pad  |-->|sink|   |src|-->|sink|   |src|--+-->
handler
 *  |              |    |-----'   '------------'   '------------'  |
 *  '--------------'    '------------------------------------------'
 * </pre>
 *
 * @param st Audio source state
 *
 * @return 0 if success, otherwise errorcode
 */

static int gst_setup(struct ausrc_st *st)
{
        GstBus *bus;
        GstPad *pad;

        st->loop = g_main_loop_new(NULL, FALSE);

        st->pipeline = gst_pipeline_new("pipeline");
        if (!st->pipeline) {
                warning("gst: failed to create pipeline element\n");
                return ENOMEM;
        }

        /********************* Player BIN **************************/

        st->source = gst_element_factory_make("playbin", "source");
        if (!st->source) {
                warning("gst: failed to create playbin source element\n");
                return ENOMEM;
        }

        /********************* My BIN **************************/

        st->bin = gst_bin_new("mybin");

        st->capsfilt = gst_element_factory_make("capsfilter", NULL);
        if (!st->capsfilt) {
                warning("gst: failed to create capsfilter element\n");
                return ENOMEM;
        }

        set_caps(st);

        st->sink = gst_element_factory_make("fakesink", "sink");
        if (!st->sink) {
                warning("gst: failed to create sink element\n");
                return ENOMEM;
        }

        gst_bin_add_many(GST_BIN(st->bin), st->capsfilt, st->sink, NULL);
        gst_element_link_many(st->capsfilt, st->sink, NULL);

        /* add ghostpad */
        pad = gst_element_get_pad(st->capsfilt, "sink");
        gst_element_add_pad(st->bin, gst_ghost_pad_new("sink", pad));
        gst_object_unref(GST_OBJECT(pad));

        /* put all elements in a bin */
        gst_bin_add_many(GST_BIN(st->pipeline), st->source, NULL);

        /* Override audio-sink handoff handler */
        g_object_set(G_OBJECT(st->sink), "signal-handoffs", TRUE, NULL);
        g_signal_connect(st->sink, "handoff", G_CALLBACK(handoff_handler), st);
        g_object_set(G_OBJECT(st->source), "audio-sink", st->bin, NULL);

        /********************* Misc **************************/

        /* Bus watch */
        bus = gst_pipeline_get_bus(GST_PIPELINE(st->pipeline));
        gst_bus_add_watch(bus, bus_watch_handler, st);
        gst_object_unref(bus);

        /* Set URI */
        g_object_set(G_OBJECT(st->source), "uri", st->uri, NULL);

        return 0;
}



static void gst_destructor(void *arg)
{
        struct ausrc_st *st = arg;
        int err = 0;
        if (st->run) {
                st->run = false;
                g_main_loop_quit(st->loop);
                err = pthread_join(st->tid, NULL);
        }
        //deadlock will happen in this line
        gst_element_set_state(st->pipeline, GST_STATE_NULL);
        gst_object_unref(GST_OBJECT(st->pipeline));
        mem_deref(st->call_id);
        mem_deref(st->uri);
        mem_deref(st->aubuf);
}


static int gst_alloc(struct ausrc_st **stp, const struct ausrc *as,
                     struct media_ctx **ctx,
                     struct ausrc_prm *prm, const char *device, const char
*call_id,
                     ausrc_read_h *rh, ausrc_error_h *errh, void *arg)
{
        struct ausrc_st *st;
        int err;
        (void)ctx;
        err = gst_setup(st);
        if (err)
                goto out;

        st->run  = true;
        err = pthread_create(&st->tid, NULL, thread, st);
        if (err) {
                st->run = false;
                goto out;
        }

out:
        if (err)
                mem_deref(st);
        else
                *stp = st;

        return err;
}



--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: deadlock when stop gstreamer

Shuke
could any one helps?



--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: deadlock when stop gstreamer

Nicolas Dufresne-5
Le lundi 28 janvier 2019 à 02:32 -0600, Shuke a écrit :
> could any one helps?

First step, install debug symbols for your copy of GStreamer, and then
produce a full backtrace using gdb. Only with this information we will
be able to help your further.

>
>
>
> --
> Sent from: http://gstreamer-devel.966125.n4.nabble.com/
> _______________________________________________
> gstreamer-devel mailing list
> [hidden email]
> https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

signature.asc (201 bytes) Download Attachment