From 1589452fdc044dc6233e73e87c0e3735c97a5495 Mon Sep 17 00:00:00 2001 From: Alexei Gradinari Date: Sat, 6 Aug 2016 11:57:08 -0400 Subject: 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 --- include/asterisk/taskprocessor.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'include') diff --git a/include/asterisk/taskprocessor.h b/include/asterisk/taskprocessor.h index e51122269..7c79036b3 100644 --- a/include/asterisk/taskprocessor.h +++ b/include/asterisk/taskprocessor.h @@ -241,6 +241,38 @@ struct ast_taskprocessor_local { int ast_taskprocessor_push_local(struct ast_taskprocessor *tps, int (*task_exe)(struct ast_taskprocessor_local *local), void *datap); +/*! + * \brief Indicate the taskprocessor is suspended. + * + * \since 13.12.0 + * + * \param tps Task processor. + * \retval 0 success + * \retval -1 failure + */ +int ast_taskprocessor_suspend(struct ast_taskprocessor *tps); + +/*! + * \brief Indicate the taskprocessor is unsuspended. + * + * \since 13.12.0 + * + * \param tps Task processor. + * \retval 0 success + * \retval -1 failure + */ +int ast_taskprocessor_unsuspend(struct ast_taskprocessor *tps); + +/*! + * \brief Get the task processor suspend status + * + * \since 13.12.0 + * + * \param tps Task processor. + * \retval non-zero if the task processor is suspended + */ +int ast_taskprocessor_is_suspended(struct ast_taskprocessor *tps); + /*! * \brief Pop a task off the taskprocessor and execute it. * -- cgit v1.2.3