From: Terry Wilson Date: Wed, 22 Feb 2012 21:08:50 +0000 (+0000) Subject: Track module use count for res_calendar X-Git-Tag: 1.8.11.0-rc1~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9a3c56977287f3d0725c275760c5f09f0294a91b;p=thirdparty%2Fasterisk.git Track module use count for res_calendar If the res_calendar module was followed immediately by one of the calendar tech modules and "core stop gracefully" was run, Asterisk would crash. This patch adds use count tracking for res_calendar so that it is unloaded after the tech modules when shutting down gracefully. It is now not possible to unload all the of the calendar modules via "module unload res_calednar.so", but it is still possible to unload them all via "module unload -h res_calendar.so". Review: https://reviewboard.asterisk.org/r/1752/ git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@356291 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/include/asterisk/calendar.h b/include/asterisk/calendar.h index 8b970ae696..54a6c6861c 100644 --- a/include/asterisk/calendar.h +++ b/include/asterisk/calendar.h @@ -25,6 +25,7 @@ #include "asterisk/linkedlists.h" #include "asterisk/lock.h" #include "asterisk/dial.h" +#include "asterisk/module.h" /*! \file calendar.h * \brief A general API for managing calendar events with Asterisk @@ -69,6 +70,7 @@ struct ast_calendar_tech { const char *type; const char *description; const char *module; + struct ast_module_user *user; int (* is_busy)(struct ast_calendar *calendar); /*!< Override default busy determination */ void *(* load_calendar)(void *data); /*!< Create private structure, add calendar events, etc. */ void *(* unref_calendar)(void *obj); /*!< Function to be called to free the private structure */ diff --git a/main/loader.c b/main/loader.c index 670c7e7e64..06f59cb6c8 100644 --- a/main/loader.c +++ b/main/loader.c @@ -239,7 +239,9 @@ void __ast_module_user_hangup_all(struct ast_module *mod) AST_LIST_LOCK(&mod->users); while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) { - ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD); + if (u->chan) { + ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD); + } ast_atomic_fetchadd_int(&mod->usecount, -1); ast_free(u); } diff --git a/res/res_calendar.c b/res/res_calendar.c index f5b803ae1a..347dce8ab0 100644 --- a/res/res_calendar.c +++ b/res/res_calendar.c @@ -496,6 +496,7 @@ int ast_calendar_register(struct ast_calendar_tech *tech) } } AST_LIST_INSERT_HEAD(&techs, tech, list); + tech->user = ast_module_user_add(NULL); AST_LIST_UNLOCK(&techs); ast_verb(2, "Registered calendar type '%s' (%s)\n", tech->type, tech->description); @@ -528,6 +529,7 @@ void ast_calendar_unregister(struct ast_calendar_tech *tech) ao2_callback(calendars, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, match_caltech_cb, tech); AST_LIST_REMOVE_CURRENT(list); + ast_module_user_remove(iter->user); ast_verb(2, "Unregistered calendar type '%s'\n", tech->type); break; }