mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-22 20:56:39 +00:00
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:
@@ -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;
|
||||
|
Reference in New Issue
Block a user