diff options
author | Matthew Jordan <mjordan@digium.com> | 2014-11-02 01:01:52 +0000 |
---|---|---|
committer | Matthew Jordan <mjordan@digium.com> | 2014-11-02 01:01:52 +0000 |
commit | 5db1c978e33de81ba887a5b6e01be3b9fb622728 (patch) | |
tree | 0b5a1425c8c016d01e2af18cba678ded530743ce /res/res_stasis.c | |
parent | 4219c40775ee89ae3d9b4218ebcf4bbded18ec23 (diff) |
res/res_stasis: Fix crash on module unload while performing operation
When the res_stasis module is unloaded, it will dispose of the apps_registry
container. This is a problem if an ARI operation is in flight that attempts
to use the registry, as the shutdown occurs in a separate thread. This patch
adds some sanity checks to the various routines that access the registry which
cause the operations to fail if the apps_registry does not exist.
Crash caught by the Asterisk Test Suite.
........
Merged revisions 426995 from http://svn.asterisk.org/svn/asterisk/branches/12
........
Merged revisions 426996 from http://svn.asterisk.org/svn/asterisk/branches/13
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@426997 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_stasis.c')
-rw-r--r-- | res/res_stasis.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/res/res_stasis.c b/res/res_stasis.c index c11f82976..99a3aed93 100644 --- a/res/res_stasis.c +++ b/res/res_stasis.c @@ -1204,6 +1204,10 @@ int stasis_app_exec(struct ast_channel *chan, const char *app_name, int argc, */ remove_stasis_end_published(chan); + if (!apps_registry) { + return -1; + } + app = ao2_find(apps_registry, app_name, OBJ_SEARCH_KEY); if (!app) { ast_log(LOG_ERROR, @@ -1364,6 +1368,10 @@ int stasis_app_send(const char *app_name, struct ast_json *message) { RAII_VAR(struct stasis_app *, app, NULL, ao2_cleanup); + if (!apps_registry) { + return -1; + } + app = ao2_find(apps_registry, app_name, OBJ_SEARCH_KEY); if (!app) { /* XXX We can do a better job handling late binding, queueing up @@ -1381,6 +1389,10 @@ static struct stasis_app *find_app_by_name(const char *app_name) { struct stasis_app *res = NULL; + if (!apps_registry) { + return NULL; + } + if (!ast_strlen_zero(app_name)) { res = ao2_find(apps_registry, app_name, OBJ_SEARCH_KEY); } @@ -1405,6 +1417,10 @@ struct ao2_container *stasis_app_get_all(void) { RAII_VAR(struct ao2_container *, apps, NULL, ao2_cleanup); + if (!apps_registry) { + return NULL; + } + apps = ast_str_container_alloc(1); if (!apps) { return NULL; @@ -1419,8 +1435,11 @@ int stasis_app_register(const char *app_name, stasis_app_cb handler, void *data) { RAII_VAR(struct stasis_app *, app, NULL, ao2_cleanup); - SCOPED_LOCK(apps_lock, apps_registry, ao2_lock, ao2_unlock); + if (!apps_registry) { + return -1; + } + ao2_lock(apps_registry); app = ao2_find(apps_registry, app_name, OBJ_SEARCH_KEY | OBJ_NOLOCK); if (app) { app_update(app, handler, data); @@ -1429,6 +1448,7 @@ int stasis_app_register(const char *app_name, stasis_app_cb handler, void *data) if (app) { ao2_link_flags(apps_registry, app, OBJ_NOLOCK); } else { + ao2_unlock(apps_registry); return -1; } } @@ -1437,6 +1457,7 @@ int stasis_app_register(const char *app_name, stasis_app_cb handler, void *data) * prevent memory leaks, and we're lazy. */ cleanup(); + ao2_unlock(apps_registry); return 0; } @@ -1448,6 +1469,10 @@ void stasis_app_unregister(const char *app_name) return; } + if (!apps_registry) { + return; + } + app = ao2_find(apps_registry, app_name, OBJ_SEARCH_KEY); if (!app) { ast_log(LOG_ERROR, @@ -1841,6 +1866,7 @@ static int unload_module(void) messaging_cleanup(); + cleanup(); ao2_cleanup(apps_registry); apps_registry = NULL; |