pbx: Deadlock between contexts container and context_merge locks
authorKevin Harwell <kharwell@digium.com>
Fri, 8 Jan 2016 22:59:44 +0000 (16:59 -0600)
committerKevin Harwell <kharwell@digium.com>
Mon, 11 Jan 2016 19:46:25 +0000 (13:46 -0600)
commit7760029f19ae4985b9806cb1c882482e2be823a5
treeafdf0d7c0fe31fe690aaa64a2ab5fefb39f2b095
parenta146bde1f728b2bc5901ccb1292c1cb330196a58
pbx: Deadlock between contexts container and context_merge locks

Recent changes (ASTERISK-25394 commit 2bd27d12223fe33b58c453965ed5c6ed3af7c4f5)
introduced the possibility of a deadlock. Due to the mentioned modifications
ast_change_hints now needs to keep both merge/delete and state callbacks from
occurring while it executes. Unfortunately, sometimes ast_change_hints can be
called with the contexts container locked. When this happens it's possible for
another thread to grab the context_merge_lock before the thread calling into
ast_change_hints does and then try to obtain the contexts container lock. This
of course causes a deadlock between the two threads. The thread calling into
ast_change_hints waits for the other thread to release context_merge_lock and
the other thread is waiting on that one to release the contexts container lock.

Unfortunately, there is not a great way to fix this problem. When hints change,
the subsequent state callbacks cannot run at the same time as a merge/delete,
nor when the usual state callbacks do. This patch alleviates the problem by
having those particular callbacks (the ones run after a hint change) occur in a
serialized task. By moving the context_merge_lock to a task it can now safely be
attempted or held without a deadlock occurring.

ASTERISK-25640 #close
Reported by: Krzysztof Trempala

Change-Id: If2210ea241afd1585dc2594c16faff84579bf302
main/pbx.c