mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-02 19:16:15 +00:00
res_pjsip_exten_state,res_pjsip_mwi: Allow unload on shutdown
Commit f66f77f
last year prevents the res_pjsip_exten_state and
res_pjsip_mwi modules from unloading due to possible pjproject
asserts if the modules are reloaded. A side effect of the
implementation is that the taskprocessors these modules use aren't
being released. When asterisk is doing a graceful shutdown, it
waits AST_TASKPROCESSOR_SHUTDOWN_MAX_WAIT seconds for all
taskprocessors to stop but since those 2 modules don't release
theirs, the shutdown hangs for that amount of time.
This change allows the modules to be unloaded and their resources to
be released when ast_shutdown_final is true.
Resolves: #379
This commit is contained in:
committed by
res_pjsip_mwi: Allow unload on shutdown
parent
96420f3d48
commit
3e4024ee20
@@ -973,33 +973,35 @@ static int publisher_stop(struct ast_sip_outbound_publish_client *client)
|
|||||||
|
|
||||||
static int unload_module(void)
|
static int unload_module(void)
|
||||||
{
|
{
|
||||||
#if 0
|
/*
|
||||||
ast_sip_unregister_event_publisher_handler(&dialog_publisher);
|
|
||||||
ast_sip_unregister_subscription_handler(&dialog_handler);
|
|
||||||
ast_sip_unregister_event_publisher_handler(&presence_publisher);
|
|
||||||
ast_sip_unregister_subscription_handler(&presence_handler);
|
|
||||||
|
|
||||||
ast_extension_state_del(0, exten_state_publisher_state_cb);
|
|
||||||
|
|
||||||
ast_taskprocessor_unreference(publish_exten_state_serializer);
|
|
||||||
publish_exten_state_serializer = NULL;
|
|
||||||
|
|
||||||
ao2_cleanup(publishers);
|
|
||||||
publishers = NULL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
/* If we were allowed to unload, the above is what we would do.
|
|
||||||
* pjsip_evsub_register_pkg is called by ast_sip_register_subscription_handler
|
* pjsip_evsub_register_pkg is called by ast_sip_register_subscription_handler
|
||||||
* but there is no corresponding unregister function, so unloading
|
* but there is no corresponding unregister function, so unloading
|
||||||
* a module does not remove the event package. If this module is ever
|
* a module does not remove the event package. If this module is ever
|
||||||
* loaded again, then pjproject will assert and cause a crash.
|
* loaded again, then pjproject will assert and cause a crash.
|
||||||
* For that reason, we must not be allowed to unload, but if
|
* For that reason, we must only be allowed to unload when
|
||||||
* a pjsip_evsub_unregister_pkg API is added in the future
|
* asterisk is shutting down. If a pjsip_evsub_unregister_pkg
|
||||||
* then we should go back to unloading the module as intended.
|
* API is added in the future then we should go back to unloading
|
||||||
|
* the module as intended.
|
||||||
*/
|
*/
|
||||||
return -1;
|
|
||||||
#endif
|
if (ast_shutdown_final()) {
|
||||||
|
ast_sip_unregister_event_publisher_handler(&dialog_publisher);
|
||||||
|
ast_sip_unregister_subscription_handler(&dialog_handler);
|
||||||
|
ast_sip_unregister_event_publisher_handler(&presence_publisher);
|
||||||
|
ast_sip_unregister_subscription_handler(&presence_handler);
|
||||||
|
|
||||||
|
ast_extension_state_del(0, exten_state_publisher_state_cb);
|
||||||
|
|
||||||
|
ast_taskprocessor_unreference(publish_exten_state_serializer);
|
||||||
|
publish_exten_state_serializer = NULL;
|
||||||
|
|
||||||
|
ao2_cleanup(publishers);
|
||||||
|
publishers = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int load_module(void)
|
static int load_module(void)
|
||||||
|
@@ -1524,43 +1524,45 @@ static int reload(void)
|
|||||||
|
|
||||||
static int unload_module(void)
|
static int unload_module(void)
|
||||||
{
|
{
|
||||||
#if 0
|
/*
|
||||||
struct ao2_container *unsolicited_mwi;
|
|
||||||
|
|
||||||
ast_sorcery_observer_remove(ast_sip_get_sorcery(), "global", &global_observer);
|
|
||||||
ast_sorcery_observer_remove(ast_sip_get_sorcery(), "contact", &mwi_contact_observer);
|
|
||||||
|
|
||||||
unsolicited_mwi = ao2_global_obj_replace(mwi_unsolicited, NULL);
|
|
||||||
if (unsolicited_mwi) {
|
|
||||||
ao2_callback(unsolicited_mwi, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe, NULL);
|
|
||||||
ao2_ref(unsolicited_mwi, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
ao2_global_obj_release(mwi_solicited);
|
|
||||||
|
|
||||||
if (ast_serializer_pool_destroy(mwi_serializer_pool)) {
|
|
||||||
ast_log(LOG_WARNING, "Unload incomplete. Try again later\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
mwi_serializer_pool = NULL;
|
|
||||||
|
|
||||||
ast_sip_unregister_subscription_handler(&mwi_handler);
|
|
||||||
|
|
||||||
ast_free(default_voicemail_extension);
|
|
||||||
default_voicemail_extension = NULL;
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
/* If we were allowed to unload, the above is what we would do.
|
|
||||||
* pjsip_evsub_register_pkg is called by ast_sip_register_subscription_handler
|
* pjsip_evsub_register_pkg is called by ast_sip_register_subscription_handler
|
||||||
* but there is no corresponding unregister function, so unloading
|
* but there is no corresponding unregister function, so unloading
|
||||||
* a module does not remove the event package. If this module is ever
|
* a module does not remove the event package. If this module is ever
|
||||||
* loaded again, then pjproject will assert and cause a crash.
|
* loaded again, then pjproject will assert and cause a crash.
|
||||||
* For that reason, we must not be allowed to unload, but if
|
* For that reason, we must only be allowed to unload when
|
||||||
* a pjsip_evsub_unregister_pkg API is added in the future
|
* asterisk is shutting down. If a pjsip_evsub_unregister_pkg
|
||||||
* then we should go back to unloading the module as intended.
|
* API is added in the future then we should go back to unloading
|
||||||
|
* the module as intended.
|
||||||
*/
|
*/
|
||||||
return -1;
|
|
||||||
#endif
|
if (ast_shutdown_final()) {
|
||||||
|
struct ao2_container *unsolicited_mwi;
|
||||||
|
|
||||||
|
ast_sorcery_observer_remove(ast_sip_get_sorcery(), "global", &global_observer);
|
||||||
|
ast_sorcery_observer_remove(ast_sip_get_sorcery(), "contact", &mwi_contact_observer);
|
||||||
|
|
||||||
|
unsolicited_mwi = ao2_global_obj_replace(mwi_unsolicited, NULL);
|
||||||
|
if (unsolicited_mwi) {
|
||||||
|
ao2_callback(unsolicited_mwi, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe, NULL);
|
||||||
|
ao2_ref(unsolicited_mwi, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ao2_global_obj_release(mwi_solicited);
|
||||||
|
|
||||||
|
if (ast_serializer_pool_destroy(mwi_serializer_pool)) {
|
||||||
|
ast_log(LOG_WARNING, "Unload incomplete. Try again later\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
mwi_serializer_pool = NULL;
|
||||||
|
|
||||||
|
ast_sip_unregister_subscription_handler(&mwi_handler);
|
||||||
|
|
||||||
|
ast_free(default_voicemail_extension);
|
||||||
|
default_voicemail_extension = NULL;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int load_module(void)
|
static int load_module(void)
|
||||||
|
Reference in New Issue
Block a user