<p>Kevin Harwell has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/13002">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_pjsip/res_pjsip_mwi: use centralized serializer pools<br><br>Both res_pjsip and res_pjsip_mwi made use of serializer pools. However, they<br>both implemented their own serializer pool functionality that was pretty much<br>identical in each of the source files. This patch removes the duplicated code,<br>and uses the new 'ast_serializer_pool' object instead.<br><br>Additionally res_pjsip_mwi enables a shutdown group on the pool since if the<br>timing was right the module could be unloaded while taskprocessor threads still<br>needed to execute, thus causing a crash.<br><br>Change-Id: I959b0805ad024585bbb6276593118be34fbf6e1d<br>---<br>M include/asterisk/res_pjsip.h<br>M res/res_pjsip.c<br>M res/res_pjsip_mwi.c<br>3 files changed, 55 insertions(+), 194 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/02/13002/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h</span><br><span>index e295765..a78311d 100644</span><br><span>--- a/include/asterisk/res_pjsip.h</span><br><span>+++ b/include/asterisk/res_pjsip.h</span><br><span>@@ -2954,6 +2954,11 @@</span><br><span> long ast_sip_threadpool_queue_size(void);</span><br><span> </span><br><span> /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Retrieve the SIP threadpool object</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+struct ast_threadpool *ast_sip_threadpool(void);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span> * \brief Retrieve transport state</span><br><span> * \since 13.7.1</span><br><span> *</span><br><span>diff --git a/res/res_pjsip.c b/res/res_pjsip.c</span><br><span>index 7123938..ed6245a 100644</span><br><span>--- a/res/res_pjsip.c</span><br><span>+++ b/res/res_pjsip.c</span><br><span>@@ -34,6 +34,7 @@</span><br><span> #include "asterisk/utils.h"</span><br><span> #include "asterisk/astobj2.h"</span><br><span> #include "asterisk/module.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/serializer.h"</span><br><span> #include "asterisk/threadpool.h"</span><br><span> #include "asterisk/taskprocessor.h"</span><br><span> #include "asterisk/uuid.h"</span><br><span>@@ -2829,7 +2830,7 @@</span><br><span> #define SERIALIZER_POOL_SIZE 8</span><br><span> </span><br><span> /*! Pool of serializers to use if not supplied. */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_taskprocessor *serializer_pool[SERIALIZER_POOL_SIZE];</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_serializer_pool *sip_serializer_pool;</span><br><span> </span><br><span> static pjsip_endpoint *ast_pjsip_endpoint;</span><br><span> </span><br><span>@@ -4568,71 +4569,10 @@</span><br><span> return ast_sip_create_serializer_group(name, NULL);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/*!</span><br><span style="color: hsl(0, 100%, 40%);">- * \internal</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief Shutdown the serializers in the default pool.</span><br><span style="color: hsl(0, 100%, 40%);">- * \since 14.0.0</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * \return Nothing</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-static void serializer_pool_shutdown(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int idx;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for (idx = 0; idx < SERIALIZER_POOL_SIZE; ++idx) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_taskprocessor_unreference(serializer_pool[idx]);</span><br><span style="color: hsl(0, 100%, 40%);">- serializer_pool[idx] = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*!</span><br><span style="color: hsl(0, 100%, 40%);">- * \internal</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief Setup the serializers in the default pool.</span><br><span style="color: hsl(0, 100%, 40%);">- * \since 14.0.0</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval 0 on success.</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval -1 on error.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-static int serializer_pool_setup(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];</span><br><span style="color: hsl(0, 100%, 40%);">- int idx;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for (idx = 0; idx < SERIALIZER_POOL_SIZE; ++idx) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Create name with seq number appended. */</span><br><span style="color: hsl(0, 100%, 40%);">- ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/default");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- serializer_pool[idx] = ast_sip_create_serializer(tps_name);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!serializer_pool[idx]) {</span><br><span style="color: hsl(0, 100%, 40%);">- serializer_pool_shutdown();</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_taskprocessor *serializer_pool_pick(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int idx;</span><br><span style="color: hsl(0, 100%, 40%);">- int pos = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!serializer_pool[0]) {</span><br><span style="color: hsl(0, 100%, 40%);">- return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for (idx = 1; idx < SERIALIZER_POOL_SIZE; ++idx) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_taskprocessor_size(serializer_pool[idx]) < ast_taskprocessor_size(serializer_pool[pos])) {</span><br><span style="color: hsl(0, 100%, 40%);">- pos = idx;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return serializer_pool[pos];</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> int ast_sip_push_task(struct ast_taskprocessor *serializer, int (*sip_task)(void *), void *task_data)</span><br><span> {</span><br><span> if (!serializer) {</span><br><span style="color: hsl(0, 100%, 40%);">- serializer = serializer_pool_pick();</span><br><span style="color: hsl(120, 100%, 40%);">+ serializer = ast_serializer_pool_get(sip_serializer_pool);</span><br><span> }</span><br><span> </span><br><span> return ast_taskprocessor_push(serializer, sip_task, task_data);</span><br><span>@@ -4713,7 +4653,7 @@</span><br><span> {</span><br><span> if (!serializer) {</span><br><span> /* Caller doesn't care which PJSIP serializer the task executes under. */</span><br><span style="color: hsl(0, 100%, 40%);">- serializer = serializer_pool_pick();</span><br><span style="color: hsl(120, 100%, 40%);">+ serializer = ast_serializer_pool_get(sip_serializer_pool);</span><br><span> if (!serializer) {</span><br><span> /* No serializer picked to execute the task */</span><br><span> return -1;</span><br><span>@@ -5071,6 +5011,11 @@</span><br><span> return ast_threadpool_queue_size(sip_threadpool);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct ast_threadpool *ast_sip_threadpool(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return sip_threadpool;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #ifdef TEST_FRAMEWORK</span><br><span> AST_TEST_DEFINE(xml_sanitization_end_null)</span><br><span> {</span><br><span>@@ -5142,7 +5087,7 @@</span><br><span> * These calls need the pjsip endpoint and serializer to clean up.</span><br><span> * If they're not set, then there's nothing to clean up anyway.</span><br><span> */</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_pjsip_endpoint && serializer_pool[0]) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_pjsip_endpoint && sip_serializer_pool) {</span><br><span> ast_res_pjsip_cleanup_options_handling();</span><br><span> ast_res_pjsip_cleanup_message_filter();</span><br><span> ast_sip_destroy_distributor();</span><br><span>@@ -5278,7 +5223,9 @@</span><br><span> goto error;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (serializer_pool_setup()) {</span><br><span style="color: hsl(120, 100%, 40%);">+ sip_serializer_pool = ast_serializer_pool_create(</span><br><span style="color: hsl(120, 100%, 40%);">+ "pjsip/default", SERIALIZER_POOL_SIZE, sip_threadpool, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!sip_serializer_pool) {</span><br><span> ast_log(LOG_ERROR, "Failed to create SIP serializer pool. Aborting load\n");</span><br><span> goto error;</span><br><span> }</span><br><span>@@ -5351,7 +5298,7 @@</span><br><span> </span><br><span> /* These functions all check for NULLs and are safe to call at any time */</span><br><span> ast_sip_destroy_scheduler();</span><br><span style="color: hsl(0, 100%, 40%);">- serializer_pool_shutdown();</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_serializer_pool_destroy(sip_serializer_pool);</span><br><span> ast_threadpool_shutdown(sip_threadpool);</span><br><span> </span><br><span> return AST_MODULE_LOAD_DECLINE;</span><br><span>@@ -5382,7 +5329,7 @@</span><br><span> */</span><br><span> ast_sip_push_task_wait_servant(NULL, unload_pjsip, NULL);</span><br><span> ast_sip_destroy_scheduler();</span><br><span style="color: hsl(0, 100%, 40%);">- serializer_pool_shutdown();</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_serializer_pool_destroy(sip_serializer_pool);</span><br><span> ast_threadpool_shutdown(sip_threadpool);</span><br><span> </span><br><span> return 0;</span><br><span>diff --git a/res/res_pjsip_mwi.c b/res/res_pjsip_mwi.c</span><br><span>index 82f6e46..6961455 100644</span><br><span>--- a/res/res_pjsip_mwi.c</span><br><span>+++ b/res/res_pjsip_mwi.c</span><br><span>@@ -36,6 +36,7 @@</span><br><span> #include "asterisk/logger.h"</span><br><span> #include "asterisk/astobj2.h"</span><br><span> #include "asterisk/taskprocessor.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/serializer.h"</span><br><span> #include "asterisk/sorcery.h"</span><br><span> #include "asterisk/stasis.h"</span><br><span> #include "asterisk/mwi.h"</span><br><span>@@ -57,8 +58,11 @@</span><br><span> /*! Number of serializers in pool if one not supplied. */</span><br><span> #define MWI_SERIALIZER_POOL_SIZE 8</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! Max timeout for all threads to join during an unload. */</span><br><span style="color: hsl(120, 100%, 40%);">+#define MAX_UNLOAD_TIMEOUT_TIME 10 /* Seconds */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! Pool of serializers to use if not supplied. */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_taskprocessor *mwi_serializer_pool[MWI_SERIALIZER_POOL_SIZE];</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_serializer_pool *mwi_serializer_pool;</span><br><span> </span><br><span> static void mwi_subscription_shutdown(struct ast_sip_subscription *sub);</span><br><span> static void mwi_to_ami(struct ast_sip_subscription *sub, struct ast_str **buf);</span><br><span>@@ -129,117 +133,6 @@</span><br><span> char id[1];</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/*!</span><br><span style="color: hsl(0, 100%, 40%);">- * \internal</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief Shutdown the serializers in the mwi pool.</span><br><span style="color: hsl(0, 100%, 40%);">- * \since 13.12.0</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * \return Nothing</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-static void mwi_serializer_pool_shutdown(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int idx;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for (idx = 0; idx < MWI_SERIALIZER_POOL_SIZE; ++idx) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_taskprocessor_unreference(mwi_serializer_pool[idx]);</span><br><span style="color: hsl(0, 100%, 40%);">- mwi_serializer_pool[idx] = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*!</span><br><span style="color: hsl(0, 100%, 40%);">- * \internal</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief Setup the serializers in the mwi pool.</span><br><span style="color: hsl(0, 100%, 40%);">- * \since 13.12.0</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval 0 on success.</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval -1 on error.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-static int mwi_serializer_pool_setup(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];</span><br><span style="color: hsl(0, 100%, 40%);">- int idx;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for (idx = 0; idx < MWI_SERIALIZER_POOL_SIZE; ++idx) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Create name with seq number appended. */</span><br><span style="color: hsl(0, 100%, 40%);">- ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/mwi");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- mwi_serializer_pool[idx] = ast_sip_create_serializer(tps_name);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!mwi_serializer_pool[idx]) {</span><br><span style="color: hsl(0, 100%, 40%);">- mwi_serializer_pool_shutdown();</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*!</span><br><span style="color: hsl(0, 100%, 40%);">- * \internal</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief Pick a mwi serializer from the pool.</span><br><span style="color: hsl(0, 100%, 40%);">- * \since 13.12.0</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval least queue size task processor.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_taskprocessor *get_mwi_serializer(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int idx;</span><br><span style="color: hsl(0, 100%, 40%);">- int pos;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!mwi_serializer_pool[0]) {</span><br><span style="color: hsl(0, 100%, 40%);">- return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for (pos = idx = 0; idx < MWI_SERIALIZER_POOL_SIZE; ++idx) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_taskprocessor_size(mwi_serializer_pool[idx]) < ast_taskprocessor_size(mwi_serializer_pool[pos])) {</span><br><span style="color: hsl(0, 100%, 40%);">- pos = idx;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return mwi_serializer_pool[pos];</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*!</span><br><span style="color: hsl(0, 100%, 40%);">- * \internal</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief Set taskprocessor alert levels for the serializers in the mwi pool.</span><br><span style="color: hsl(0, 100%, 40%);">- * \since 13.12.0</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval 0 on success.</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval -1 on error.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-static int mwi_serializer_set_alert_levels(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int idx;</span><br><span style="color: hsl(0, 100%, 40%);">- long tps_queue_high;</span><br><span style="color: hsl(0, 100%, 40%);">- long tps_queue_low;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!mwi_serializer_pool[0]) {</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- tps_queue_high = ast_sip_get_mwi_tps_queue_high();</span><br><span style="color: hsl(0, 100%, 40%);">- if (tps_queue_high <= 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(AST_LOG_WARNING, "Invalid taskprocessor high water alert trigger level '%ld'\n",</span><br><span style="color: hsl(0, 100%, 40%);">- tps_queue_high);</span><br><span style="color: hsl(0, 100%, 40%);">- tps_queue_high = AST_TASKPROCESSOR_HIGH_WATER_LEVEL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- tps_queue_low = ast_sip_get_mwi_tps_queue_low();</span><br><span style="color: hsl(0, 100%, 40%);">- if (tps_queue_low < -1 || tps_queue_high < tps_queue_low) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(AST_LOG_WARNING, "Invalid taskprocessor low water clear alert level '%ld'\n",</span><br><span style="color: hsl(0, 100%, 40%);">- tps_queue_low);</span><br><span style="color: hsl(0, 100%, 40%);">- tps_queue_low = -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for (idx = 0; idx < MWI_SERIALIZER_POOL_SIZE; ++idx) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_taskprocessor_alert_set_levels(mwi_serializer_pool[idx], tps_queue_low, tps_queue_high)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(AST_LOG_WARNING, "Failed to set alert levels for MWI serializer pool #%d.\n",</span><br><span style="color: hsl(0, 100%, 40%);">- idx);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> static void mwi_stasis_cb(void *userdata, struct stasis_subscription *sub,</span><br><span> struct stasis_message *msg);</span><br><span> </span><br><span>@@ -1218,7 +1111,7 @@</span><br><span> struct mwi_subscription *mwi_sub = obj;</span><br><span> struct ast_taskprocessor *serializer = mwi_sub->is_solicited</span><br><span> ? ast_sip_subscription_get_serializer(mwi_sub->sip_sub)</span><br><span style="color: hsl(0, 100%, 40%);">- : get_mwi_serializer();</span><br><span style="color: hsl(120, 100%, 40%);">+ : ast_serializer_pool_get(mwi_serializer_pool);</span><br><span> </span><br><span> if (ast_sip_push_task(serializer, serialized_notify, ao2_bump(mwi_sub))) {</span><br><span> ao2_ref(mwi_sub, -1);</span><br><span>@@ -1233,7 +1126,8 @@</span><br><span> struct mwi_subscription *mwi_sub = userdata;</span><br><span> </span><br><span> if (stasis_subscription_final_message(sub, msg)) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_sip_push_task(NULL, serialized_cleanup, ao2_bump(mwi_sub))) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_sip_push_task(ast_serializer_pool_get(mwi_serializer_pool),</span><br><span style="color: hsl(120, 100%, 40%);">+ serialized_cleanup, ao2_bump(mwi_sub))) {</span><br><span> ao2_ref(mwi_sub, -1);</span><br><span> }</span><br><span> return;</span><br><span>@@ -1396,7 +1290,8 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_sip_push_task(get_mwi_serializer(), serialized_notify, ao2_bump(mwi_sub))) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_sip_push_task(ast_serializer_pool_get(mwi_serializer_pool),</span><br><span style="color: hsl(120, 100%, 40%);">+ serialized_notify, ao2_bump(mwi_sub))) {</span><br><span> ao2_ref(mwi_sub, -1);</span><br><span> }</span><br><span> </span><br><span>@@ -1518,7 +1413,8 @@</span><br><span> return;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ast_sip_push_task(NULL, send_initial_notify_all, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sip_push_task(ast_serializer_pool_get(mwi_serializer_pool),</span><br><span style="color: hsl(120, 100%, 40%);">+ send_initial_notify_all, NULL);</span><br><span> </span><br><span> stasis_unsubscribe(sub);</span><br><span> }</span><br><span>@@ -1527,7 +1423,8 @@</span><br><span> {</span><br><span> ast_free(default_voicemail_extension);</span><br><span> default_voicemail_extension = ast_sip_get_default_voicemail_extension();</span><br><span style="color: hsl(0, 100%, 40%);">- mwi_serializer_set_alert_levels();</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_serializer_pool_set_alerts(mwi_serializer_pool,</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sip_get_mwi_tps_queue_high(), ast_sip_get_mwi_tps_queue_low());</span><br><span> }</span><br><span> </span><br><span> static struct ast_sorcery_observer global_observer = {</span><br><span>@@ -1548,14 +1445,16 @@</span><br><span> return AST_MODULE_LOAD_DECLINE;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (mwi_serializer_pool_setup()) {</span><br><span style="color: hsl(120, 100%, 40%);">+ mwi_serializer_pool = ast_serializer_pool_create("pjsip/mwi",</span><br><span style="color: hsl(120, 100%, 40%);">+ MWI_SERIALIZER_POOL_SIZE, ast_sip_threadpool(), MAX_UNLOAD_TIMEOUT_TIME);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mwi_serializer_pool) {</span><br><span> ast_log(AST_LOG_WARNING, "Failed to create MWI serializer pool. The default SIP pool will be used for MWI\n");</span><br><span> }</span><br><span> </span><br><span> solicited_mwi = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, MWI_BUCKETS,</span><br><span> mwi_sub_hash, NULL, mwi_sub_cmp);</span><br><span> if (!solicited_mwi) {</span><br><span style="color: hsl(0, 100%, 40%);">- mwi_serializer_pool_shutdown();</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_serializer_pool_destroy(mwi_serializer_pool);</span><br><span> ast_sip_unregister_subscription_handler(&mwi_handler);</span><br><span> return AST_MODULE_LOAD_DECLINE;</span><br><span> }</span><br><span>@@ -1563,7 +1462,7 @@</span><br><span> unsolicited_mwi = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, MWI_BUCKETS,</span><br><span> mwi_sub_hash, NULL, mwi_sub_cmp);</span><br><span> if (!unsolicited_mwi) {</span><br><span style="color: hsl(0, 100%, 40%);">- mwi_serializer_pool_shutdown();</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_serializer_pool_destroy(mwi_serializer_pool);</span><br><span> ast_sip_unregister_subscription_handler(&mwi_handler);</span><br><span> ao2_ref(solicited_mwi, -1);</span><br><span> return AST_MODULE_LOAD_DECLINE;</span><br><span>@@ -1576,7 +1475,8 @@</span><br><span> if (!ast_sip_get_mwi_disable_initial_unsolicited()) {</span><br><span> create_mwi_subscriptions();</span><br><span> if (ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_sip_push_task(NULL, send_initial_notify_all, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sip_push_task(ast_serializer_pool_get(mwi_serializer_pool),</span><br><span style="color: hsl(120, 100%, 40%);">+ send_initial_notify_all, NULL);</span><br><span> } else {</span><br><span> struct stasis_subscription *sub;</span><br><span> </span><br><span>@@ -1594,13 +1494,22 @@</span><br><span> ast_sorcery_observer_remove(ast_sip_get_sorcery(), "global", &global_observer);</span><br><span> ast_sorcery_observer_remove(ast_sip_get_sorcery(), "contact", &mwi_contact_observer);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ao2_callback(unsolicited_mwi, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_ref(unsolicited_mwi, -1);</span><br><span style="color: hsl(0, 100%, 40%);">- unsolicited_mwi = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (unsolicited_mwi) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_callback(unsolicited_mwi, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_ref(unsolicited_mwi, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ unsolicited_mwi = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ao2_cleanup(solicited_mwi);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (solicited_mwi) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_ref(solicited_mwi, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ solicited_mwi = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- mwi_serializer_pool_shutdown();</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_serializer_pool_destroy(mwi_serializer_pool)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_WARNING, "Unload incomplete. Try again later\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ mwi_serializer_pool = NULL;</span><br><span> </span><br><span> ast_sip_unregister_subscription_handler(&mwi_handler);</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/13002">change 13002</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/13002"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 16 </div>
<div style="display:none"> Gerrit-Change-Id: I959b0805ad024585bbb6276593118be34fbf6e1d </div>
<div style="display:none"> Gerrit-Change-Number: 13002 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>