Merge "res_pjsip: Refactor load_module/unload_module"
This commit is contained in:
commit
1783edd181
216
res/res_pjsip.c
216
res/res_pjsip.c
|
@ -3949,31 +3949,54 @@ static int reload_configuration_task(void *obj)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int load_module(void)
|
||||
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]) {
|
||||
ast_res_pjsip_cleanup_options_handling();
|
||||
ast_sip_destroy_distributor();
|
||||
ast_res_pjsip_destroy_configuration();
|
||||
ast_sip_destroy_system();
|
||||
ast_sip_destroy_global_headers();
|
||||
internal_sip_unregister_service(&supplement_module);
|
||||
}
|
||||
|
||||
if (monitor_thread) {
|
||||
stop_monitor_thread();
|
||||
monitor_thread = NULL;
|
||||
}
|
||||
|
||||
if (memory_pool) {
|
||||
pj_pool_release(memory_pool);
|
||||
memory_pool = NULL;
|
||||
}
|
||||
|
||||
ast_pjsip_endpoint = NULL;
|
||||
|
||||
if (caching_pool.lock) {
|
||||
pj_caching_pool_destroy(&caching_pool);
|
||||
}
|
||||
|
||||
pj_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int load_pjsip(void)
|
||||
{
|
||||
pj_status_t status;
|
||||
|
||||
/* The third parameter is just copied from
|
||||
* example code from PJLIB. This can be adjusted
|
||||
* if necessary.
|
||||
*/
|
||||
pj_status_t status;
|
||||
struct ast_threadpool_options options;
|
||||
|
||||
CHECK_PJPROJECT_MODULE_LOADED();
|
||||
|
||||
if (pj_init() != PJ_SUCCESS) {
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
}
|
||||
|
||||
if (pjlib_util_init() != PJ_SUCCESS) {
|
||||
pj_shutdown();
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
}
|
||||
|
||||
pj_caching_pool_init(&caching_pool, NULL, 1024 * 1024);
|
||||
if (pjsip_endpt_create(&caching_pool.factory, "SIP", &ast_pjsip_endpoint) != PJ_SUCCESS) {
|
||||
ast_log(LOG_ERROR, "Failed to create PJSIP endpoint structure. Aborting load\n");
|
||||
pj_caching_pool_destroy(&caching_pool);
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* PJSIP will automatically try to add a Max-Forwards header. Since we want to control that,
|
||||
|
@ -3984,10 +4007,7 @@ static int load_module(void)
|
|||
memory_pool = pj_pool_create(&caching_pool.factory, "SIP", 1024, 1024, NULL);
|
||||
if (!memory_pool) {
|
||||
ast_log(LOG_ERROR, "Failed to create memory pool for SIP. Aborting load\n");
|
||||
pjsip_endpt_destroy(ast_pjsip_endpoint);
|
||||
ast_pjsip_endpoint = NULL;
|
||||
pj_caching_pool_destroy(&caching_pool);
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!pj_gethostip(pj_AF_INET(), &host_ip_ipv4)) {
|
||||
|
@ -4000,42 +4020,6 @@ static int load_module(void)
|
|||
ast_verb(3, "Local IPv6 address determined to be: %s\n", host_ip_ipv6_string);
|
||||
}
|
||||
|
||||
if (ast_sip_initialize_system()) {
|
||||
ast_log(LOG_ERROR, "Failed to initialize SIP 'system' configuration section. Aborting load\n");
|
||||
pj_pool_release(memory_pool);
|
||||
memory_pool = NULL;
|
||||
pjsip_endpt_destroy(ast_pjsip_endpoint);
|
||||
ast_pjsip_endpoint = NULL;
|
||||
pj_caching_pool_destroy(&caching_pool);
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
}
|
||||
|
||||
sip_get_threadpool_options(&options);
|
||||
options.thread_start = sip_thread_start;
|
||||
sip_threadpool = ast_threadpool_create("SIP", NULL, &options);
|
||||
if (!sip_threadpool) {
|
||||
ast_log(LOG_ERROR, "Failed to create SIP threadpool. Aborting load\n");
|
||||
ast_sip_destroy_system();
|
||||
pj_pool_release(memory_pool);
|
||||
memory_pool = NULL;
|
||||
pjsip_endpt_destroy(ast_pjsip_endpoint);
|
||||
ast_pjsip_endpoint = NULL;
|
||||
pj_caching_pool_destroy(&caching_pool);
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
}
|
||||
|
||||
if (serializer_pool_setup()) {
|
||||
ast_log(LOG_ERROR, "Failed to create SIP serializer pool. Aborting load\n");
|
||||
ast_threadpool_shutdown(sip_threadpool);
|
||||
ast_sip_destroy_system();
|
||||
pj_pool_release(memory_pool);
|
||||
memory_pool = NULL;
|
||||
pjsip_endpt_destroy(ast_pjsip_endpoint);
|
||||
ast_pjsip_endpoint = NULL;
|
||||
pj_caching_pool_destroy(&caching_pool);
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
}
|
||||
|
||||
pjsip_tsx_layer_init_module(ast_pjsip_endpoint);
|
||||
pjsip_ua_init_module(ast_pjsip_endpoint, NULL);
|
||||
|
||||
|
@ -4044,28 +4028,61 @@ static int load_module(void)
|
|||
NULL, PJ_THREAD_DEFAULT_STACK_SIZE * 2, 0, &monitor_thread);
|
||||
if (status != PJ_SUCCESS) {
|
||||
ast_log(LOG_ERROR, "Failed to start SIP monitor thread. Aborting load\n");
|
||||
ast_sip_destroy_system();
|
||||
pj_pool_release(memory_pool);
|
||||
memory_pool = NULL;
|
||||
pjsip_endpt_destroy(ast_pjsip_endpoint);
|
||||
ast_pjsip_endpoint = NULL;
|
||||
pj_caching_pool_destroy(&caching_pool);
|
||||
goto error;
|
||||
}
|
||||
|
||||
return AST_MODULE_LOAD_SUCCESS;
|
||||
|
||||
error:
|
||||
unload_pjsip(NULL);
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
}
|
||||
|
||||
static int load_module(void)
|
||||
{
|
||||
struct ast_threadpool_options options;
|
||||
|
||||
CHECK_PJPROJECT_MODULE_LOADED();
|
||||
|
||||
/* pjproject and config_system need to be initialized before all else */
|
||||
if (pj_init() != PJ_SUCCESS) {
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
}
|
||||
|
||||
if (pjlib_util_init() != PJ_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ast_sip_initialize_system()) {
|
||||
ast_log(LOG_ERROR, "Failed to initialize SIP 'system' configuration section. Aborting load\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* The serializer needs threadpool and threadpool needs pjproject to be initialized so it's next */
|
||||
sip_get_threadpool_options(&options);
|
||||
options.thread_start = sip_thread_start;
|
||||
sip_threadpool = ast_threadpool_create("SIP", NULL, &options);
|
||||
if (!sip_threadpool) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (serializer_pool_setup()) {
|
||||
ast_log(LOG_ERROR, "Failed to create SIP serializer pool. Aborting load\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Now load all the pjproject infrastructure. */
|
||||
if (load_pjsip()) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
ast_sip_initialize_dns();
|
||||
|
||||
ast_sip_initialize_global_headers();
|
||||
|
||||
if (ast_res_pjsip_initialize_configuration()) {
|
||||
ast_log(LOG_ERROR, "Failed to initialize SIP configuration. Aborting load\n");
|
||||
ast_sip_destroy_global_headers();
|
||||
stop_monitor_thread();
|
||||
ast_sip_destroy_system();
|
||||
pj_pool_release(memory_pool);
|
||||
memory_pool = NULL;
|
||||
pjsip_endpt_destroy(ast_pjsip_endpoint);
|
||||
ast_pjsip_endpoint = NULL;
|
||||
pj_caching_pool_destroy(&caching_pool);
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
ast_sip_initialize_resolver();
|
||||
|
@ -4073,31 +4090,12 @@ static int load_module(void)
|
|||
|
||||
if (ast_sip_initialize_distributor()) {
|
||||
ast_log(LOG_ERROR, "Failed to register distributor module. Aborting load\n");
|
||||
ast_res_pjsip_destroy_configuration();
|
||||
ast_sip_destroy_global_headers();
|
||||
stop_monitor_thread();
|
||||
ast_sip_destroy_system();
|
||||
pj_pool_release(memory_pool);
|
||||
memory_pool = NULL;
|
||||
pjsip_endpt_destroy(ast_pjsip_endpoint);
|
||||
ast_pjsip_endpoint = NULL;
|
||||
pj_caching_pool_destroy(&caching_pool);
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (internal_sip_register_service(&supplement_module)) {
|
||||
ast_log(LOG_ERROR, "Failed to initialize supplement hooks. Aborting load\n");
|
||||
ast_sip_destroy_distributor();
|
||||
ast_res_pjsip_destroy_configuration();
|
||||
ast_sip_destroy_global_headers();
|
||||
stop_monitor_thread();
|
||||
ast_sip_destroy_system();
|
||||
pj_pool_release(memory_pool);
|
||||
memory_pool = NULL;
|
||||
pjsip_endpt_destroy(ast_pjsip_endpoint);
|
||||
ast_pjsip_endpoint = NULL;
|
||||
pj_caching_pool_destroy(&caching_pool);
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
ast_res_pjsip_init_options_handling(0);
|
||||
|
@ -4109,6 +4107,14 @@ static int load_module(void)
|
|||
ast_pjproject_ref();
|
||||
|
||||
return AST_MODULE_LOAD_SUCCESS;
|
||||
|
||||
error:
|
||||
/* These functions all check for NULLs and are safe to call at any time */
|
||||
unload_pjsip(NULL);
|
||||
serializer_pool_shutdown();
|
||||
ast_threadpool_shutdown(sip_threadpool);
|
||||
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
}
|
||||
|
||||
static int reload_module(void)
|
||||
|
@ -4125,32 +4131,11 @@ static int reload_module(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int unload_pjsip(void *data)
|
||||
{
|
||||
ast_cli_unregister_multiple(cli_commands, ARRAY_LEN(cli_commands));
|
||||
ast_res_pjsip_cleanup_options_handling();
|
||||
ast_sip_destroy_distributor();
|
||||
ast_res_pjsip_destroy_configuration();
|
||||
ast_sip_destroy_system();
|
||||
ast_sip_destroy_global_headers();
|
||||
internal_sip_unregister_service(&supplement_module);
|
||||
if (monitor_thread) {
|
||||
stop_monitor_thread();
|
||||
}
|
||||
if (memory_pool) {
|
||||
pj_pool_release(memory_pool);
|
||||
memory_pool = NULL;
|
||||
}
|
||||
ast_pjsip_endpoint = NULL;
|
||||
pj_caching_pool_destroy(&caching_pool);
|
||||
pj_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unload_module(void)
|
||||
{
|
||||
AST_TEST_UNREGISTER(xml_sanitization_end_null);
|
||||
AST_TEST_UNREGISTER(xml_sanitization_exceeds_buffer);
|
||||
ast_cli_unregister_multiple(cli_commands, ARRAY_LEN(cli_commands));
|
||||
|
||||
/* The thread this is called from cannot call PJSIP/PJLIB functions,
|
||||
* so we have to push the work to the threadpool to handle
|
||||
|
@ -4160,7 +4145,6 @@ static int unload_module(void)
|
|||
serializer_pool_shutdown();
|
||||
ast_threadpool_shutdown(sip_threadpool);
|
||||
|
||||
ast_sip_destroy_cli();
|
||||
ast_pjproject_unref();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -2024,18 +2024,24 @@ int ast_res_pjsip_initialize_configuration(void)
|
|||
|
||||
void ast_res_pjsip_destroy_configuration(void)
|
||||
{
|
||||
if (!sip_sorcery) {
|
||||
return;
|
||||
}
|
||||
|
||||
ast_sorcery_observer_remove(sip_sorcery, CONTACT_STATUS, &state_contact_status_observer);
|
||||
ast_sorcery_observer_remove(sip_sorcery, "contact", &state_contact_observer);
|
||||
ast_sip_destroy_sorcery_global();
|
||||
ast_sip_destroy_sorcery_location();
|
||||
ast_sip_destroy_sorcery_auth();
|
||||
ast_sip_destroy_sorcery_transport();
|
||||
ast_sorcery_unref(sip_sorcery);
|
||||
sip_sorcery = NULL;
|
||||
ast_manager_unregister(AMI_SHOW_ENDPOINT);
|
||||
ast_manager_unregister(AMI_SHOW_ENDPOINTS);
|
||||
ast_cli_unregister_multiple(cli_commands, ARRAY_LEN(cli_commands));
|
||||
ast_sip_unregister_cli_formatter(endpoint_formatter);
|
||||
ast_sip_unregister_cli_formatter(channel_formatter);
|
||||
ast_sorcery_unref(sip_sorcery);
|
||||
ast_sip_destroy_cli();
|
||||
ao2_cleanup(persistent_endpoints);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue