]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_sorcery_memory_cache.c: Shutdown in a less crash potential order. 53/1353/1
authorRichard Mudgett <rmudgett@digium.com>
Thu, 1 Oct 2015 19:27:34 +0000 (14:27 -0500)
committerRichard Mudgett <rmudgett@digium.com>
Thu, 1 Oct 2015 22:25:37 +0000 (17:25 -0500)
Basically you should shutdown in the opposite order of how you setup since
later setup pieces likely depend on earlier setup pieces.  e.g.,
Registering your external API with the rest of the system should be the
last thing setup and the first thing unregistered during shutdown.

Change-Id: I5715765b723100c8d3c2642e9e72cc7ad5ad115e

res/res_sorcery_memory_cache.c

index 620c3464828a3c152845934206d2624d0e21ddd0..bc385b4ae316958e1f149df677b93b3ffd6112fd 100644 (file)
@@ -2480,22 +2480,6 @@ cleanup:
 
 static int unload_module(void)
 {
-       if (sched) {
-               ast_sched_context_destroy(sched);
-               sched = NULL;
-       }
-
-       ao2_cleanup(caches);
-
-       ast_sorcery_wizard_unregister(&memory_cache_object_wizard);
-
-       ast_cli_unregister_multiple(cli_memory_cache, ARRAY_LEN(cli_memory_cache));
-
-       ast_manager_unregister("SorceryMemoryCacheExpireObject");
-       ast_manager_unregister("SorceryMemoryCacheExpire");
-       ast_manager_unregister("SorceryMemoryCacheStaleObject");
-       ast_manager_unregister("SorceryMemoryCacheStale");
-
        AST_TEST_UNREGISTER(open_with_valid_options);
        AST_TEST_UNREGISTER(open_with_invalid_options);
        AST_TEST_UNREGISTER(create_and_retrieve);
@@ -2505,6 +2489,27 @@ static int unload_module(void)
        AST_TEST_UNREGISTER(expiration);
        AST_TEST_UNREGISTER(stale);
 
+       ast_manager_unregister("SorceryMemoryCacheExpireObject");
+       ast_manager_unregister("SorceryMemoryCacheExpire");
+       ast_manager_unregister("SorceryMemoryCacheStaleObject");
+       ast_manager_unregister("SorceryMemoryCacheStale");
+
+       ast_cli_unregister_multiple(cli_memory_cache, ARRAY_LEN(cli_memory_cache));
+
+       ast_sorcery_wizard_unregister(&memory_cache_object_wizard);
+
+       /*
+        * XXX There is the potential to leak memory if there are pending
+        * next-cache-expiration and stale-cache-update tasks in the scheduler.
+        */
+       if (sched) {
+               ast_sched_context_destroy(sched);
+               sched = NULL;
+       }
+
+       ao2_cleanup(caches);
+       caches = NULL;
+
        return 0;
 }
 
@@ -2512,6 +2517,14 @@ static int load_module(void)
 {
        int res;
 
+       caches = ao2_container_alloc(CACHES_CONTAINER_BUCKET_SIZE, sorcery_memory_cache_hash,
+               sorcery_memory_cache_cmp);
+       if (!caches) {
+               ast_log(LOG_ERROR, "Failed to create container for configured caches\n");
+               unload_module();
+               return AST_MODULE_LOAD_DECLINE;
+       }
+
        sched = ast_sched_context_create();
        if (!sched) {
                ast_log(LOG_ERROR, "Failed to create scheduler for cache management\n");
@@ -2525,14 +2538,6 @@ static int load_module(void)
                return AST_MODULE_LOAD_DECLINE;
        }
 
-       caches = ao2_container_alloc(CACHES_CONTAINER_BUCKET_SIZE, sorcery_memory_cache_hash,
-               sorcery_memory_cache_cmp);
-       if (!caches) {
-               ast_log(LOG_ERROR, "Failed to create container for configured caches\n");
-               unload_module();
-               return AST_MODULE_LOAD_DECLINE;
-       }
-
        if (ast_sorcery_wizard_register(&memory_cache_object_wizard)) {
                unload_module();
                return AST_MODULE_LOAD_DECLINE;