adaptivedemux: Deadlock between Stream Pad and Manifest lock
Submitted by dav..@..io.com
Link to original bug (#787878)
Description
This deadlock happens fairly regularly whilst trying to play a variant HLS with multiple audio renditions (http://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8 in my case).
One of the gst_adaptive_demux_stream_download_loop threads calls gst_pad_set_active with the manifest lock taken and that blocks waiting for GST_PAD_STREAM_LOCK. The other implicated thread has called into _src_chain of adaptivedemux with the Pad Stream lock taken and is waiting for the manifest lock. Deadlock ensues.
Thread 26 (LWP 1536):
#0 __libc_do_syscall () at ../sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:46
#1 0xb693a490 in __lll_lock_wait (futex=0xadd3d030, private=0) at lowlevellock.c:46
#2 0xb6934b1e in __GI___pthread_mutex_lock (mutex=0xadd3d030) at pthread_mutex_lock.c:115
#3 0xb26d2516 in post_activate (new_mode=GST_PAD_MODE_NONE, pad=0x77c24560) at ../../clone/gst/gstpad.c:1015
#4 activate_mode_internal (pad=pad@entry=0x77c24560, parent=parent@entry=0x7f9c4a88, mode=mode@entry=GST_PAD_MODE_PUSH, active=active@entry=0) at ../../clone/gst/gstpad.c:1186
#5 0xb26d2bc6 in gst_pad_set_active (pad=0x77c24560, active=active@entry=0) at ../../clone/gst/gstpad.c:1080
#6 0x7de831aa in gst_adaptive_demux_stream_download_uri (demux=demux@entry=0x7f9c4a88, stream=stream@entry=0xabd2f480, uri=uri@entry=0xae580cc0 <error: Cannot access memory at address 0xae580cc0>, start=start@entry=0, end=-1, http_status=http_status@entry=0x7b7fea84) at ../../../../clone/gst-libs/gst/adaptivedemux/gstadaptivedemux.c:3164
#7 0x7de84f10 in gst_adaptive_demux_stream_download_fragment (stream=0xabd2f480) at ../../../../clone/gst-libs/gst/adaptivedemux/gstadaptivedemux.c:3320
#8 gst_adaptive_demux_stream_download_loop (stream=0xabd2f480) at ../../../../clone/gst-libs/gst/adaptivedemux/gstadaptivedemux.c:3634
#9 0xb26fc000 in gst_task_func (task=0x7cc0fac8) at ../../clone/gst/gsttask.c:335
#10 0xb6838002 in g_thread_pool_thread_proxy (data=<optimized out>) at ../../glib-2.50.2/glib/gthreadpool.c:307
#11 0xb6837a6e in g_thread_proxy (data=0x7ae6aaf0) at ../../glib-2.50.2/glib/gthread.c:784
#12 0xb69328d2 in start_thread (arg=0x0) at pthread_create.c:335
#13 0xb0a20bb2 in ?? () at ../sysdeps/unix/sysv/linux/arm/clone.S:86
Thread 22 (LWP 1532):
#0 __libc_do_syscall () at ../sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:46
#1 0xb693a4bc in __lll_lock_wait (futex=0x7d225840, private=0) at lowlevellock.c:43
#2 0xb6934b1e in __GI___pthread_mutex_lock (mutex=0x7d225840) at pthread_mutex_lock.c:115
#3 0x7de7cd7a in _src_chain (pad=<optimized out>, parent=0x7f9c4a88, buffer=0x7cc90338) at ../../../../clone/gst-libs/gst/adaptivedemux/gstadaptivedemux.c:2460
#4 0xb26ce8f8 in gst_pad_chain_data_unchecked (data=0x7cc90338, type=4112, pad=0x77c7b800) at ../../clone/gst/gstpad.c:4205
#5 gst_pad_push_data (pad=pad@entry=0x72f76038, type=type@entry=4112, data=data@entry=0x7cc90338) at ../../clone/gst/gstpad.c:4464
#6 0xb26d5d40 in gst_pad_push (pad=pad@entry=0x72f76038, buffer=buffer@entry=0x7cc90338) at ../../clone/gst/gstpad.c:4583
#7 0xb26bf934 in gst_proxy_pad_chain_default (pad=0xad5dde60, parent=<optimized out>, buffer=0x7cc90338) at ../../clone/gst/gstghostpad.c:127
#8 0xb26ce8f8 in gst_pad_chain_data_unchecked (data=0x7cc90338, type=4112, pad=0xad5dde60) at ../../clone/gst/gstpad.c:4205
#9 gst_pad_push_data (pad=pad@entry=0x77c7b560, type=type@entry=4112, data=data@entry=0x7cc90338) at ../../clone/gst/gstpad.c:4464
#10 0xb26d5d40 in gst_pad_push (pad=0x77c7b560, buffer=buffer@entry=0x7cc90338) at ../../clone/gst/gstpad.c:4583
#11 0x7f82e642 in gst_queue_push_one (queue=0x77203d20) at ../../../clone/plugins/elements/gstqueue.c:1365
#12 gst_queue_loop (pad=<optimized out>) at ../../../clone/plugins/elements/gstqueue.c:1517
#13 0xb26fc000 in gst_task_func (task=0x7cc54028) at ../../clone/gst/gsttask.c:335
#14 0xb6838002 in g_thread_pool_thread_proxy (data=<optimized out>) at ../../glib-2.50.2/glib/gthreadpool.c:307
#15 0xb6837a6e in g_thread_proxy (data=0xadfd30f0) at ../../glib-2.50.2/glib/gthread.c:784
#16 0xb69328d2 in start_thread (arg=0x0) at pthread_create.c:335
#17 0xb0a20bb2 in ?? () at ../sysdeps/unix/sysv/linux/arm/clone.S:86
Looking through adaptivedemux.c there are numerous places where gst_pad_set_active is called with the Manifest lock held, though in gst_adaptive_demux_expose_streams it appears to be deliberately dropped. However, gst_adaptive_demux_reset which has near identical code doesn't drop the Manifest lock.
I'll work on a patch.
Version: 1.12.2