]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_pjsip_exten_state,res_pjsip_mwi: Allow unload on shutdown
authorGeorge Joseph <gjoseph@sangoma.com>
Thu, 19 Oct 2023 13:40:26 +0000 (07:40 -0600)
committerAsterisk Development Team <asteriskteam@digium.com>
Fri, 12 Jan 2024 18:32:12 +0000 (18:32 +0000)
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
(cherry picked from commit b9ee6644406b6290e4a23eb54d99d69ce48b966b)

res/res_pjsip_exten_state.c
res/res_pjsip_mwi.c

index 1b29091849ab0ca2a7d87a5e16c4899657c44c95..374730bc8201fea403f407ec2218c05bb55bf117 100644 (file)
@@ -973,33 +973,35 @@ static int publisher_stop(struct ast_sip_outbound_publish_client *client)
 
 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
         * but there is no corresponding unregister function, so unloading
         * a module does not remove the event package. If this module is ever
         * loaded again, then pjproject will assert and cause a crash.
-        * For that reason, we must not be allowed to unload, but if
-        * a pjsip_evsub_unregister_pkg API is added in the future
-        * then we should go back to unloading the module as intended.
+        * For that reason, we must only be allowed to unload when
+        * asterisk is shutting down.  If a pjsip_evsub_unregister_pkg
+        * 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)
index dfe5481f334a29e88bd80dfb48f025751f14d14c..36f6af275610a6a56e6d7d9b8d6a3ad468c5d3c7 100644 (file)
@@ -1524,43 +1524,45 @@ static int reload(void)
 
 static int unload_module(void)
 {
-#if 0
-       struct ao2_container *unsolicited_mwi;
+       /*
+        * pjsip_evsub_register_pkg is called by ast_sip_register_subscription_handler
+        * but there is no corresponding unregister function, so unloading
+        * a module does not remove the event package. If this module is ever
+        * loaded again, then pjproject will assert and cause a crash.
+        * For that reason, we must only be allowed to unload when
+        * asterisk is shutting down.  If a pjsip_evsub_unregister_pkg
+        * API is added in the future then we should go back to unloading
+        * the module as intended.
+        */
 
-       ast_sorcery_observer_remove(ast_sip_get_sorcery(), "global", &global_observer);
-       ast_sorcery_observer_remove(ast_sip_get_sorcery(), "contact", &mwi_contact_observer);
+       if (ast_shutdown_final()) {
+               struct ao2_container *unsolicited_mwi;
 
-       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);
-       }
+               ast_sorcery_observer_remove(ast_sip_get_sorcery(), "global", &global_observer);
+               ast_sorcery_observer_remove(ast_sip_get_sorcery(), "contact", &mwi_contact_observer);
 
-       ao2_global_obj_release(mwi_solicited);
+               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);
+               }
 
-       if (ast_serializer_pool_destroy(mwi_serializer_pool)) {
-               ast_log(LOG_WARNING, "Unload incomplete. Try again later\n");
-               return -1;
-       }
-       mwi_serializer_pool = NULL;
+               ao2_global_obj_release(mwi_solicited);
 
-       ast_sip_unregister_subscription_handler(&mwi_handler);
+               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_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
-        * but there is no corresponding unregister function, so unloading
-        * a module does not remove the event package. If this module is ever
-        * loaded again, then pjproject will assert and cause a crash.
-        * For that reason, we must not be allowed to unload, but if
-        * a pjsip_evsub_unregister_pkg API is added in the future
-        * then we should go back to unloading the module as intended.
-        */
-       return -1;
-#endif
+               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)