[Home]

Summary:ASTERISK-16713: potential channel/queue deadlock when setqueuevar enabled
Reporter:Ben Winslow (rain)Labels:
Date Opened:2010-09-22 15:51:29Date Closed:2010-11-19 15:42:11.000-0600
Priority:CriticalRegression?No
Status:Closed/CompleteComponents:Applications/app_queue
Versions:Frequency of
Occurrence
Related
Issues:
Environment:Attachments:
Description:When setqueuevar is enabled in app_queue, the potential exists for one thread to lock a call_queue structure with a channel lock held while another thread locks the channel with the call_queue lock held.  The resulting deadlock will end up crippling Asterisk since quite a few parts of Asterisk will traverse the channel list.

At several points in app_queue (in my case, end_bridge_callback), a queue will be locked before calling set_queue_variables (which pulls data directly out of the queue structure); this is fine, but when setqueuevar is actually enabled, the call to pbx_builtin_setvar_multiple will lock the channel.  Meanwhile, another thread may be calling ast_do_masquerade() to clone the same channel, resulting in a lock on the same channel (clonechan.)  Later in the masquerade, the datastore fixup functions are called, and queue_transfer_fixup's call to update_queue() will result in an attempt to lock the related queue (or all queues if shared_lastcall is enabled.)

This deadlock occurred for me on 1.6.2.6 but appears to present in 1.6.2.13 as well.  In my case, do_masquerade() got the channel lock while end_bridge_callback() got the queue lock.

****** ADDITIONAL INFORMATION ******

Queue config:
setqueuevar = yes
shared_lastcall = yes

All agents in the queue were Local channels.  Unfortunately, I lost the core I forced from this deadlock, so I can't provide backtraces for the two deadlocked threads.  I can tell you that they were (roughly)...

Thread A: ... -> ast_bridge_call -> app_queue.c end_bridge_callback [queue lock happens here] -> set_queue_variables -> pbx_builtin_setvar_multiple -> pbx_builtin_setvar_helper -> ast_channel_lock

Thread B: ... -> ast_do_masquerade [channel lock happens here] -> queue_transfer_fixup -> update_queue -> ao2_lock
Comments:By: Digium Subversion (svnbot) 2010-11-19 15:40:22.000-0600

Repository: asterisk
Revision: 295670

U   branches/1.8/apps/app_queue.c

------------------------------------------------------------------------
r295670 | bbryant | 2010-11-19 15:40:21 -0600 (Fri, 19 Nov 2010) | 8 lines

Patch for deadlock from ordering issue between channel/queue locks in app_queue
(set_queue_variables).

(closes issue ASTERISK-16713)
Reported by: rain

Review: https://reviewboard.asterisk.org/r/1018/

------------------------------------------------------------------------

http://svn.digium.com/view/asterisk?view=rev&revision=295670

By: Digium Subversion (svnbot) 2010-11-19 15:42:11.000-0600

Repository: asterisk
Revision: 295671

_U  trunk/
U   trunk/apps/app_queue.c

------------------------------------------------------------------------
r295671 | bbryant | 2010-11-19 15:42:11 -0600 (Fri, 19 Nov 2010) | 15 lines

Merged revisions 295670 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.8

........
 r295670 | bbryant | 2010-11-19 16:40:21 -0500 (Fri, 19 Nov 2010) | 8 lines
 
 Patch for deadlock from ordering issue between channel/queue locks in app_queue
 (set_queue_variables).
 
 (closes issue ASTERISK-16713)
 Reported by: rain
 
 Review: https://reviewboard.asterisk.org/r/1018/
........

------------------------------------------------------------------------

http://svn.digium.com/view/asterisk?view=rev&revision=295671