[Bug 721253] New: multiqueue may cause hanging

GStreamer (bugzilla.gnome.org) bugzilla at gnome.org
Mon Dec 30 17:59:44 PST 2013


https://bugzilla.gnome.org/show_bug.cgi?id=721253
  GStreamer | gst-plugins | 1.0.5

           Summary: multiqueue may cause hanging
    Classification: Platform
           Product: GStreamer
           Version: 1.0.5
        OS/Version: Linux
            Status: UNCONFIRMED
          Severity: critical
          Priority: Normal
         Component: gst-plugins
        AssignedTo: gstreamer-bugs at lists.freedesktop.org
        ReportedBy: zhangyanping210 at yahoo.com.cn
         QAContact: gstreamer-bugs at lists.freedesktop.org
     GNOME version: ---


I use playbin to playing a http stream.
When the pipeline did not construct finished, I called 
gst_element_set_state(playbin, GST_STATE_NULL);
At this time, application hang.
This is call stack of threads that cause haning.

======================

Thread 5 (Thread 0x2b98a480 (LWP 22769)):
#0  0x2b054a04 in __lll_lock_wait () from /lib/libpthread.so.0
#1  0x2b04ea50 in pthread_mutex_lock () from /lib/libpthread.so.0
#2  0x2ae44c1c in g_rec_mutex_lock (mutex=0x11c414) at gthread-posix.c:377
#3  0x2ac45084 in post_activate (pad=0x11c3c8, new_mode=GST_PAD_MODE_NONE) at
gstpad.c:917
#4  0x2ac45a68 in gst_pad_activate_mode (pad=0x11c3c8, mode=GST_PAD_MODE_PUSH,
active=0) at gstpad.c:1121
#5  0x2ac45470 in gst_pad_set_active (pad=0x11c3c8, active=0) at gstpad.c:989
#6  0x2ac28818 in activate_pads (vpad=0x2b9892c0, ret=0x2b9892f8,
active=0x2b989330) at gstelement.c:2679
#7  0x2ac39f34 in gst_iterator_fold (it=0x11dc90, func=0x2ac287d4
<activate_pads>, ret=0x2b9892f8, user_data=0x2b989330)
    at gstiterator.c:614
#8  0x2ac288e4 in iterator_activate_fold_with_resync (iter=0x11dc90,
func=0x2ac287d4 <activate_pads>, user_data=0x2b989330)
    at gstelement.c:2699
#9  0x2ac28a68 in gst_element_pads_activate (element=0xd0f68, active=0) at
gstelement.c:2744
#10 0x2ac28e88 in gst_element_change_state_func (element=0xd0f68,
transition=GST_STATE_CHANGE_PAUSED_TO_READY)
    at gstelement.c:2807
#11 0x2cec4c30 in gst_multi_queue_change_state (element=0xd0f68,
transition=GST_STATE_CHANGE_PAUSED_TO_READY)
    at gstmultiqueue.c:723
#12 0x2ac283a4 in gst_element_change_state (element=0xd0f68,
transition=GST_STATE_CHANGE_PAUSED_TO_READY)
    at gstelement.c:2594
#13 0x2ac281d0 in gst_element_set_state_func (element=0xd0f68,
state=GST_STATE_READY) at gstelement.c:2550
#14 0x2ac27d00 in gst_element_set_state (element=0xd0f68,
state=GST_STATE_READY) at gstelement.c:2451
#15 0x2abfc190 in gst_bin_element_set_state (bin=0xc75e0, element=0xd0f68,
base_time=236686776584302, start_time=660426640, 
    current=GST_STATE_PAUSED, next=GST_STATE_READY) at gstbin.c:2308
#16 0x2abfda08 in gst_bin_change_state_func (element=0xc75e0,
transition=GST_STATE_CHANGE_PAUSED_TO_READY) at gstbin.c:2612
#17 0x2ac5914c in gst_pipeline_change_state (element=0xc75e0,
transition=GST_STATE_CHANGE_PAUSED_TO_READY)
    at gstpipeline.c:468
#18 0x2c9ac390 in gst_play_bin_change_state (element=0xc75e0,
transition=GST_STATE_CHANGE_PAUSED_TO_READY)
    at gstplaybin3.c:1913
#19 0x2ac283a4 in gst_element_change_state (element=0xc75e0,
transition=GST_STATE_CHANGE_PAUSED_TO_READY)
    at gstelement.c:2594
#20 0x2ac277c8 in gst_element_continue_state (element=0xc75e0,
ret=GST_STATE_CHANGE_SUCCESS) at gstelement.c:2305
#21 0x2ac285b0 in gst_element_change_state (element=0xc75e0,
transition=GST_STATE_CHANGE_PLAYING_TO_PAUSED)
    at gstelement.c:2631
#22 0x2ac281d0 in gst_element_set_state_func (element=0xc75e0,
state=GST_STATE_NULL) at gstelement.c:2550
#23 0x2ac27d00 in gst_element_set_state (element=0xc75e0, state=GST_STATE_NULL)
at gstelement.c:2451

=================================

Thread 3 (Thread 0x2d6fe480 (LWP 22776)):
#0  0x2b0517c4 in pthread_cond_wait@@GLIBC_2.4 () from /lib/libpthread.so.0
#1  0x2ae45160 in g_cond_wait (cond=0x1852a4, mutex=0xd1078) at
gthread-posix.c:746
#2  0x2cec8394 in gst_multi_queue_sink_query (pad=0x11c3c8, parent=0xd0f68,
query=0x11c988) at gstmultiqueue.c:1614
#3  0x2ac4e6bc in gst_pad_query (pad=0x11c3c8, query=0x11c988) at gstpad.c:3548
#4  0x2ac4f1d4 in gst_pad_peer_query (pad=0x184c28, query=0x11c988) at
gstpad.c:3684
#5  0x2e044aa8 in qtdemux_do_allocation (qtdemux=0x1c03c8, stream=0x192a90) at
qtdemux.c:5130
#6  0x2e045a08 in gst_qtdemux_add_stream (qtdemux=0x1c03c8, stream=0x192a90,
list=0x192ec8) at qtdemux.c:5343
#7  0x2e05232c in qtdemux_expose_streams (qtdemux=0x1c03c8) at qtdemux.c:7925
#8  0x2e040530 in gst_qtdemux_chain (sinkpad=0x1c0900, parent=0x1c03c8,
inbuf=0x192888) at qtdemux.c:4310
#9  0x2ac4fa70 in gst_pad_chain_data_unchecked (pad=0x1c0900, type=4112,
data=0x192888) at gstpad.c:3790
#10 0x2ac5083c in gst_pad_push_data (pad=0xcf810, type=4112, data=0x192888) at
gstpad.c:4011
#11 0x2ac50f14 in gst_pad_push (pad=0xcf810, buffer=0x192888) at gstpad.c:4116
#12 0x2cee7ec8 in gst_type_find_element_chain (pad=0xcf4f8, parent=0xc72c8,
buffer=0x192888) at gsttypefindelement.c:828
#13 0x2ac4fa70 in gst_pad_chain_data_unchecked (pad=0xcf4f8, type=4112,
data=0x192888) at gstpad.c:3790
#14 0x2ac5083c in gst_pad_push_data (pad=0xce1c0, type=4112, data=0x192888) at
gstpad.c:4011
#15 0x2ac50f14 in gst_pad_push (pad=0xce1c0, buffer=0x192888) at gstpad.c:4116
---Type <return> to continue, or q <return> to quit---
#16 0x2ced0124 in gst_queue_push_one (queue=0xcda90) at gstqueue.c:1057
#17 0x2ced0f84 in gst_queue_loop (pad=0xce1c0) at gstqueue.c:1175
#18 0x2ac9193c in gst_task_func (task=0xd1c38) at gsttask.c:316

===========================

I found the root cause is at function gst_multi_queue_sink_query,

g_cond_wait (&sq->query_handled, &mq->qlock);

It will wait the query condition to be signaled. But because the whole pileline
did not construct finished and want to stop immediately, the sq->query_handled
have no chance to be signaled.

So at function gst_multi_queue_change_state


    case GST_STATE_CHANGE_PAUSED_TO_READY:{
      GList *tmp;

      /* Un-wait all waiting pads */
      GST_MULTI_QUEUE_MUTEX_LOCK (mqueue);
      for (tmp = mqueue->queues; tmp; tmp = g_list_next (tmp)) {
        sq = (GstSingleQueue *) tmp->data;
        sq->flushing = TRUE;
        g_cond_signal (&sq->turn);

       g_cond_signal (&sq->query_handled);    //I add this line ===========
      }
      GST_MULTI_QUEUE_MUTEX_UNLOCK (mqueue);
      break;
    }

And I test serveral hours to do quick switch:
1. create playin
2. set state playing
3. sleep 100 ms
4. set state null

This will be OK.

//==========================
And I check the codes of 1.2.1, there are some other lines will call
g_cond_signal (&sq->query_handled).

But I think add it to gst_multi_queue_change_state is better and safer.

-- 
Configure bugmail: https://bugzilla.gnome.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.


More information about the gstreamer-bugs mailing list