summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2012-06-12 14:07:13 +0000
committerMatthew Jordan <mjordan@digium.com>2012-06-12 14:07:13 +0000
commit8bc3c1e20fe11204b6aa39ba0d23fcee67b7813e (patch)
tree181ee410caf4143b8938390e89447750bab0bd81 /channels
parentafa03bd3107c6116f3252451def0498248cf8ffc (diff)
Fix deadlock in SIP transfers that involve a REFER request
In r367163, "send to voicemail" functionality was added to the SIP channel driver. This required updating the party redirecting information for the channel based on the headers provided in the REFER request. When the redirecting party information is updated on the channel, a call to ast_indicate_data occurs. Because handle_request_refer still had the sip_pvt locked, a deadlock could occur between the pbx_thread and the do_monitor thread servicing the REFER request. This patch preserves the proper locking order between the channel and the sip_pvt by ensuring that the sip_pvt is unlocked prior to updating the party redirecting information on the channel. (closes issue AST-903) Reported by: Matt Jordan patches: jira_ast_903_trunk.patch by rmudgett (license 5621) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@368793 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_sip.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 5fd1bc11a..274e9787d 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -24858,16 +24858,18 @@ static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, int
ast_party_redirecting_init(&redirecting);
memset(&update_redirecting, 0, sizeof(update_redirecting));
change_redirecting_information(p, req, &redirecting, &update_redirecting, FALSE);
+
+ /* Do not hold the pvt lock during a call that causes an indicate or an async_goto.
+ * Those functions lock channels which will invalidate locking order if the pvt lock
+ * is held.*/
+ sip_pvt_unlock(p);
ast_channel_update_redirecting(current.chan2, &redirecting, &update_redirecting);
ast_party_redirecting_free(&redirecting);
- /* Do not hold the pvt lock during the indicate and async_goto. Those functions
- * lock channels which will invalidate locking order if the pvt lock is held.*/
/* For blind transfers, move the call to the new extensions. For attended transfers on multiple
* servers - generate an INVITE with Replaces. Either way, let the dial plan decided
* indicate before masquerade so the indication actually makes it to the real channel
* when using local channels with MOH passthru */
- sip_pvt_unlock(p);
ast_indicate(current.chan2, AST_CONTROL_UNHOLD);
res = ast_async_goto(current.chan2, refer_to_context, refer_to, 1);