GNOME Bugzilla – Bug 711550
appsrc: Deadlocking because holding mutex while setting caps
Last modified: 2013-11-07 18:02:20 UTC
We have an application using rtpbin and appsrc which leaves us with a deadlock. From investigations I have found an example of some threads that lock. It seems to me that the deadlock is between the appsrc priv->mutex lock and the stream lock. I have reproduced this on 1.2.0 and 1.0.10. The appsrc line is: g_mutex_lock (&priv->mutex); The line of code from the pad is: GST_PAD_STREAM_LOCK (pad); I think the source of the issue is that appsrc list locking priv->mutex before calling gst_app_src_do_negotiate. As such I am developing a patch that avoids this locking, I think that the priv->mutex is just trying to protect variables such as the caps and new_caps flags. In this way I think that I can call do_negotiate outside of the lock as long as I ensure that the new_caps flag is acted on after caps is changed. Is there any reason why do_negotiate needs to be inside the priv->mutex lock for appsrc? I understand that it should be thread safe so it's just ensuring that the appsrc logic is correct and caps changes are responded to on the next check. This plan would also follow some of the other logic in appsrc where it unlocks before making callbacks to the application. Here are the full back traces of the two threads that appear deadlocked and the relevant mutexes
+ Trace 232726
Thread 66 (Thread 0x7f185c4ca700 (LWP 15312))
Thread 32 (Thread 0x7f1852261700 (LWP 15346))
rax 0xfffffffffffffe00 -512 rbx 0x7f18e1eaae06 139744846196230 rcx 0xffffffffffffffff -1 rdx 0x7f18a4001f40 139743807414080 rsi 0x80 128 rdi 0x7f18a4001a40 139743807412800 rbp 0x7f185c4c89e0 0x7f185c4c89e0 rsp 0x7f185c4c8928 0x7f185c4c8928 r8 0x7f18a4001a40 139743807412800 r9 0x3bd0 15312 r10 0xfffffffffffff9f8 -1544 r11 0x202 514 r12 0x7f18e132b430 139744834139184 r13 0x0 0 r14 0x4 4 r15 0x7 7 rip 0x7f18f3666287 0x7f18f3666287 <pthread_mutex_lock+103> eflags 0x202 [ IF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0 (gdb) p *(pthread_mutex_t*)0x7f18a4001a40 $2 = {__data = {__lock = 2, __count = 1, __owner = 15346, __nusers = 1, __kind = 1, __spins = 0, __list = {__prev = 0x0, __next = 0x0}}, __size = "\002\000\000\000\001\000\000\000\362;\000\000\001\000\000\000\001", '\000' <repeats 22 times>, __align = 4294967298}
Sorry bugzilla corrupted the last part of that - I think when it was processing the backtraces. Here is the register/mutex info: (gdb) thread 32 [Switching to thread 32 (Thread 0x7f1852261700 (LWP 15346))]#0 0x00007f18f366b054 in __lll_lock_wait () from /lib64/libpthread.so.0 (gdb) frame 2
+ Trace 232727
Created attachment 259196 [details] [review] Patch that does not lock priv->mutex when calling negotiate This patch does a similar thing around do_negotiate as done with the callbacks. Lock is released and then after the lock we recheck flushing status, caps have changed again and if any data is available in the queue. Tested on Mac and briefly on Centos.
commit 360ac34425539eaabfa6f6106ea1a820460f7101 Author: Tom Greenwood <tcdgreenwood@hotmail.com> Date: Thu Nov 7 15:03:34 2013 +0000 appsrc: Fix deadlock that may occur when multiple threads access appsrc at once https://bugzilla.gnome.org/show_bug.cgi?id=711550