From 6554a3b25e7dbfd50d34bda244aa08ce37187707 Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Thu, 1 Oct 2015 14:27:34 -0500 Subject: [PATCH] res_sorcery_memory_cache.c: Shutdown in a less crash potential order. 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 | 53 +++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/res/res_sorcery_memory_cache.c b/res/res_sorcery_memory_cache.c index 0a33ae401a..53fa3b9632 100644 --- a/res/res_sorcery_memory_cache.c +++ b/res/res_sorcery_memory_cache.c @@ -2482,22 +2482,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); @@ -2507,6 +2491,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; } @@ -2514,6 +2519,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"); @@ -2527,14 +2540,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;