summaryrefslogtreecommitdiff
path: root/res/res_pjsip_session.c
diff options
context:
space:
mode:
authorAlexei Gradinari <alex2grad@gmail.com>2016-08-06 11:57:08 -0400
committerAlexei Gradinari <alex2grad@gmail.com>2016-08-10 16:01:23 -0400
commit1589452fdc044dc6233e73e87c0e3735c97a5495 (patch)
treea34b5ab3dcda6be5f39b3af193dabc9e24ad0b23 /res/res_pjsip_session.c
parent805f105f8898beb0be0cdf5a7df653fdb03f730e (diff)
pjsip: Fix deadlock with suspend taskprocessor on masquerade
If both channels which should be masqueraded are in the same serializer: 1st channel will be locked waiting condition 'complete' 2nd channel will be locked waiting condition 'suspended' On heavy load system a chance that both channels will be in the same serializer 'pjsip/distibutor' is very high. To reproduce compile res_pjsip/pjsip_distributor.c with DISTRIBUTOR_POOL_SIZE=1 Steps to reproduce: 1. Party A calls Party B (bridged call 'AB') 2. Party B places Party A on hold 3. Party B calls Voicemail app (non-bridged call 'BV') 4. Party B attended transfers Party A to voicemail using REFER. 5. When asterisk masquerades calls 'AB' and 'BV', a deadlock is happened. This patch adds a suspension indicator to the taskprocessor. When a session suspends/unsuspends the serializer it sets the indicator to the appropriate state. The session checks the suspension indicator before suspend the serializer. ASTERISK-26145 #close Change-Id: Iaaebee60013a58c942ba47b1b4930a63e686663b
Diffstat (limited to 'res/res_pjsip_session.c')
-rw-r--r--res/res_pjsip_session.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 4290f6854..a41e0aa5d 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -1559,6 +1559,11 @@ void ast_sip_session_suspend(struct ast_sip_session *session)
return;
}
+ if (ast_taskprocessor_is_suspended(session->serializer)) {
+ /* The serializer already suspended. */
+ return;
+ }
+
suspender = ao2_alloc(sizeof(*suspender), sip_session_suspender_dtor);
if (!suspender) {
/* We will just have to hope that the system does not deadlock */
@@ -1583,6 +1588,8 @@ void ast_sip_session_suspend(struct ast_sip_session *session)
ast_cond_wait(&suspender->cond_suspended, ao2_object_get_lockaddr(suspender));
}
ao2_unlock(suspender);
+
+ ast_taskprocessor_suspend(session->serializer);
}
void ast_sip_session_unsuspend(struct ast_sip_session *session)
@@ -1602,6 +1609,8 @@ void ast_sip_session_unsuspend(struct ast_sip_session *session)
ao2_unlock(suspender);
ao2_ref(suspender, -1);
+
+ ast_taskprocessor_unsuspend(session->serializer);
}
/*!