res_pjsip/res_pjsip_mwi: use centralized serializer pools

Both res_pjsip and res_pjsip_mwi made use of serializer pools. However, they
both implemented their own serializer pool functionality that was pretty much
identical in each of the source files. This patch removes the duplicated code,
and uses the new 'ast_serializer_pool' object instead.

Additionally res_pjsip_mwi enables a shutdown group on the pool since if the
timing was right the module could be unloaded while taskprocessor threads still
needed to execute, thus causing a crash.

Change-Id: I959b0805ad024585bbb6276593118be34fbf6e1d
This commit is contained in:
Kevin Harwell
2019-10-02 11:34:01 -05:00
parent afc10c25ac
commit 931ef77e21
3 changed files with 64 additions and 194 deletions

View File

@@ -34,6 +34,7 @@
#include "asterisk/utils.h"
#include "asterisk/astobj2.h"
#include "asterisk/module.h"
#include "asterisk/serializer.h"
#include "asterisk/threadpool.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/uuid.h"
@@ -2829,7 +2830,7 @@
#define SERIALIZER_POOL_SIZE 8
/*! Pool of serializers to use if not supplied. */
static struct ast_taskprocessor *serializer_pool[SERIALIZER_POOL_SIZE];
static struct ast_serializer_pool *sip_serializer_pool;
static pjsip_endpoint *ast_pjsip_endpoint;
@@ -4568,71 +4569,10 @@ struct ast_taskprocessor *ast_sip_create_serializer(const char *name)
return ast_sip_create_serializer_group(name, NULL);
}
/*!
* \internal
* \brief Shutdown the serializers in the default pool.
* \since 14.0.0
*
* \return Nothing
*/
static void serializer_pool_shutdown(void)
{
int idx;
for (idx = 0; idx < SERIALIZER_POOL_SIZE; ++idx) {
ast_taskprocessor_unreference(serializer_pool[idx]);
serializer_pool[idx] = NULL;
}
}
/*!
* \internal
* \brief Setup the serializers in the default pool.
* \since 14.0.0
*
* \retval 0 on success.
* \retval -1 on error.
*/
static int serializer_pool_setup(void)
{
char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
int idx;
for (idx = 0; idx < SERIALIZER_POOL_SIZE; ++idx) {
/* Create name with seq number appended. */
ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/default");
serializer_pool[idx] = ast_sip_create_serializer(tps_name);
if (!serializer_pool[idx]) {
serializer_pool_shutdown();
return -1;
}
}
return 0;
}
static struct ast_taskprocessor *serializer_pool_pick(void)
{
int idx;
int pos = 0;
if (!serializer_pool[0]) {
return NULL;
}
for (idx = 1; idx < SERIALIZER_POOL_SIZE; ++idx) {
if (ast_taskprocessor_size(serializer_pool[idx]) < ast_taskprocessor_size(serializer_pool[pos])) {
pos = idx;
}
}
return serializer_pool[pos];
}
int ast_sip_push_task(struct ast_taskprocessor *serializer, int (*sip_task)(void *), void *task_data)
{
if (!serializer) {
serializer = serializer_pool_pick();
serializer = ast_serializer_pool_get(sip_serializer_pool);
}
return ast_taskprocessor_push(serializer, sip_task, task_data);
@@ -4713,7 +4653,7 @@ int ast_sip_push_task_wait_serializer(struct ast_taskprocessor *serializer, int
{
if (!serializer) {
/* Caller doesn't care which PJSIP serializer the task executes under. */
serializer = serializer_pool_pick();
serializer = ast_serializer_pool_get(sip_serializer_pool);
if (!serializer) {
/* No serializer picked to execute the task */
return -1;
@@ -5071,6 +5011,11 @@ long ast_sip_threadpool_queue_size(void)
return ast_threadpool_queue_size(sip_threadpool);
}
struct ast_threadpool *ast_sip_threadpool(void)
{
return sip_threadpool;
}
#ifdef TEST_FRAMEWORK
AST_TEST_DEFINE(xml_sanitization_end_null)
{
@@ -5142,7 +5087,7 @@ static int unload_pjsip(void *data)
* These calls need the pjsip endpoint and serializer to clean up.
* If they're not set, then there's nothing to clean up anyway.
*/
if (ast_pjsip_endpoint && serializer_pool[0]) {
if (ast_pjsip_endpoint && sip_serializer_pool) {
ast_res_pjsip_cleanup_options_handling();
ast_res_pjsip_cleanup_message_filter();
ast_sip_destroy_distributor();
@@ -5278,7 +5223,9 @@ static int load_module(void)
goto error;
}
if (serializer_pool_setup()) {
sip_serializer_pool = ast_serializer_pool_create(
"pjsip/default", SERIALIZER_POOL_SIZE, sip_threadpool, -1);
if (!sip_serializer_pool) {
ast_log(LOG_ERROR, "Failed to create SIP serializer pool. Aborting load\n");
goto error;
}
@@ -5351,7 +5298,7 @@ error:
/* These functions all check for NULLs and are safe to call at any time */
ast_sip_destroy_scheduler();
serializer_pool_shutdown();
ast_serializer_pool_destroy(sip_serializer_pool);
ast_threadpool_shutdown(sip_threadpool);
return AST_MODULE_LOAD_DECLINE;
@@ -5382,7 +5329,7 @@ static int unload_module(void)
*/
ast_sip_push_task_wait_servant(NULL, unload_pjsip, NULL);
ast_sip_destroy_scheduler();
serializer_pool_shutdown();
ast_serializer_pool_destroy(sip_serializer_pool);
ast_threadpool_shutdown(sip_threadpool);
return 0;