[asterisk-commits] coreyfarrell: branch 13 r431663 - in /branches/13: ./ bridges/ include/asteri...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Feb 11 09:51:36 CST 2015
Author: coreyfarrell
Date: Wed Feb 11 09:51:33 2015
New Revision: 431663
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=431663
Log:
Enable REF_DEBUG for ast_module_ref / ast_module_unref.
Add ast_module_shutdown_ref for use by modules that can
only be unloaded during graceful shutdown.
When REF_DEBUG is enabled:
* Add an empty ao2 object to struct ast_module.
* Allocate ao2 object when the module is loaded.
* Perform an ao2_ref in each place where mod->usecount is manipulated.
* ao2_cleanup on module unload.
ASTERISK-24479 #close
Reported by: Corey Farrell
Review: https://reviewboard.asterisk.org/r/4141/
........
Merged revisions 431662 from http://svn.asterisk.org/svn/asterisk/branches/11
Modified:
branches/13/ (props changed)
branches/13/bridges/bridge_builtin_features.c
branches/13/include/asterisk/module.h
branches/13/main/loader.c
Propchange: branches/13/
------------------------------------------------------------------------------
--- branch-11-merged (original)
+++ branch-11-merged Wed Feb 11 09:51:33 2015
@@ -1,1 +1,1 @@
-/branches/11:1-429517,429539,429632,429783,429804,429825,429867,429893,429982,430009,430126,430415,430487,430506,430564,430589,430795,430798,430920,430993,430996-430997,431049,431135,431187,431218,431384,431423,431617
+/branches/11:1-429517,429539,429632,429783,429804,429825,429867,429893,429982,430009,430126,430415,430487,430506,430564,430589,430795,430798,430920,430993,430996-430997,431049,431135,431187,431218,431384,431423,431617,431662
Modified: branches/13/bridges/bridge_builtin_features.c
URL: http://svnview.digium.com/svn/asterisk/branches/13/bridges/bridge_builtin_features.c?view=diff&rev=431663&r1=431662&r2=431663
==============================================================================
--- branches/13/bridges/bridge_builtin_features.c (original)
+++ branches/13/bridges/bridge_builtin_features.c Wed Feb 11 09:51:33 2015
@@ -499,6 +499,10 @@
static int unload_module(void)
{
+ ast_bridge_features_unregister(AST_BRIDGE_BUILTIN_HANGUP);
+ ast_bridge_features_unregister(AST_BRIDGE_BUILTIN_AUTOMON);
+ ast_bridge_features_unregister(AST_BRIDGE_BUILTIN_AUTOMIXMON);
+
return 0;
}
@@ -508,8 +512,8 @@
ast_bridge_features_register(AST_BRIDGE_BUILTIN_AUTOMON, feature_automonitor, NULL);
ast_bridge_features_register(AST_BRIDGE_BUILTIN_AUTOMIXMON, feature_automixmonitor, NULL);
- /* Bump up our reference count so we can't be unloaded */
- ast_module_ref(ast_module_info->self);
+ /* This module cannot be unloaded until shutdown */
+ ast_module_shutdown_ref(ast_module_info->self);
return AST_MODULE_LOAD_SUCCESS;
}
Modified: branches/13/include/asterisk/module.h
URL: http://svnview.digium.com/svn/asterisk/branches/13/include/asterisk/module.h?view=diff&rev=431663&r1=431662&r2=431663
==============================================================================
--- branches/13/include/asterisk/module.h (original)
+++ branches/13/include/asterisk/module.h Wed Feb 11 09:51:33 2015
@@ -316,8 +316,31 @@
#define ast_module_user_remove(user) __ast_module_user_remove(ast_module_info->self, user)
#define ast_module_user_hangup_all() __ast_module_user_hangup_all(ast_module_info->self)
-struct ast_module *ast_module_ref(struct ast_module *);
-void ast_module_unref(struct ast_module *);
+struct ast_module *__ast_module_ref(struct ast_module *mod, const char *file, int line, const char *func);
+void __ast_module_shutdown_ref(struct ast_module *mod, const char *file, int line, const char *func);
+void __ast_module_unref(struct ast_module *mod, const char *file, int line, const char *func);
+
+/*!
+ * \brief Hold a reference to the module
+ * \param mod Module to reference
+ * \return mod
+ *
+ * \note A module reference will prevent the module
+ * from being unloaded.
+ */
+#define ast_module_ref(mod) __ast_module_ref(mod, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+/*!
+ * \brief Prevent unload of the module before shutdown
+ * \param mod Module to hold
+ *
+ * \note This should not be balanced by a call to ast_module_unref.
+ */
+#define ast_module_shutdown_ref(mod) __ast_module_shutdown_ref(mod, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+/*!
+ * \brief Release a reference to the module
+ * \param mod Module to release
+ */
+#define ast_module_unref(mod) __ast_module_unref(mod, __FILE__, __LINE__, __PRETTY_FUNCTION__)
#if defined(__cplusplus) || defined(c_plusplus)
#define AST_MODULE_INFO(keystr, flags_to_set, desc, load_func, unload_func, reload_func, load_pri, support_level) \
Modified: branches/13/main/loader.c
URL: http://svnview.digium.com/svn/asterisk/branches/13/main/loader.c?view=diff&rev=431663&r1=431662&r2=431663
==============================================================================
--- branches/13/main/loader.c (original)
+++ branches/13/main/loader.c Wed Feb 11 09:51:33 2015
@@ -117,12 +117,17 @@
struct ast_module {
const struct ast_module_info *info;
+#ifdef REF_DEBUG
+ /* Used to get module references into REF_DEBUG logs */
+ void *ref_debug;
+#endif
void *lib; /* the shared lib, or NULL if embedded */
int usecount; /* the number of 'users' currently in this module */
struct module_user_list users; /* the list of users in the module */
struct {
unsigned int running:1;
unsigned int declined:1;
+ unsigned int keepuntilshutdown:1;
} flags;
AST_LIST_ENTRY(ast_module) list_entry;
AST_DLLIST_ENTRY(ast_module) entry;
@@ -189,6 +194,9 @@
ast_debug(5, "Registering module %s\n", info->name);
mod->info = info;
+#ifdef REF_DEBUG
+ mod->ref_debug = ao2_t_alloc(0, NULL, info->name);
+#endif
AST_LIST_HEAD_INIT(&mod->users);
/* during startup, before the loader has been initialized,
@@ -235,6 +243,9 @@
if (mod) {
ast_debug(5, "Unregistering module %s\n", info->name);
AST_LIST_HEAD_DESTROY(&mod->users);
+#ifdef REF_DEBUG
+ ao2_cleanup(mod->ref_debug);
+#endif
ast_free(mod);
}
}
@@ -253,6 +264,10 @@
AST_LIST_LOCK(&mod->users);
AST_LIST_INSERT_HEAD(&mod->users, u, entry);
AST_LIST_UNLOCK(&mod->users);
+
+#ifdef REF_DEBUG
+ ao2_ref(mod->ref_debug, +1);
+#endif
ast_atomic_fetchadd_int(&mod->usecount, +1);
@@ -278,6 +293,10 @@
return;
}
+#ifdef REF_DEBUG
+ ao2_ref(mod->ref_debug, -1);
+#endif
+
ast_atomic_fetchadd_int(&mod->usecount, -1);
ast_free(u);
@@ -293,6 +312,11 @@
if (u->chan) {
ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD);
}
+
+#ifdef REF_DEBUG
+ ao2_ref(mod->ref_debug, -1);
+#endif
+
ast_atomic_fetchadd_int(&mod->usecount, -1);
ast_free(u);
}
@@ -610,10 +634,22 @@
mod->info->unload();
}
AST_LIST_HEAD_DESTROY(&mod->users);
+#ifdef REF_DEBUG
+ ao2_cleanup(mod->ref_debug);
+#endif
free(mod);
somethingchanged = 1;
}
AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
+ if (!somethingchanged) {
+ AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
+ if (mod->flags.keepuntilshutdown) {
+ ast_module_unref(mod);
+ mod->flags.keepuntilshutdown = 0;
+ somethingchanged = 1;
+ }
+ }
+ }
} while (somethingchanged && !final);
AST_DLLIST_UNLOCK(&module_list);
@@ -1430,23 +1466,39 @@
return cur ? 0 : -1;
}
-struct ast_module *ast_module_ref(struct ast_module *mod)
+struct ast_module *__ast_module_ref(struct ast_module *mod, const char *file, int line, const char *func)
{
if (!mod) {
return NULL;
}
+#ifdef REF_DEBUG
+ __ao2_ref_debug(mod->ref_debug, +1, "", file, line, func);
+#endif
+
ast_atomic_fetchadd_int(&mod->usecount, +1);
ast_update_use_count();
return mod;
}
-void ast_module_unref(struct ast_module *mod)
+void __ast_module_shutdown_ref(struct ast_module *mod, const char *file, int line, const char *func)
+{
+ if (!mod->flags.keepuntilshutdown) {
+ __ast_module_ref(mod, file, line, func);
+ mod->flags.keepuntilshutdown = 1;
+ }
+}
+
+void __ast_module_unref(struct ast_module *mod, const char *file, int line, const char *func)
{
if (!mod) {
return;
}
+
+#ifdef REF_DEBUG
+ __ao2_ref_debug(mod->ref_debug, -1, "", file, line, func);
+#endif
ast_atomic_fetchadd_int(&mod->usecount, -1);
ast_update_use_count();
@@ -1463,3 +1515,22 @@
{
return support_level_map[support_level];
}
+
+
+
+/* The following exists for ABI compatibility */
+#undef ast_module_ref
+#undef ast_module_unref
+
+struct ast_module *ast_module_ref(struct ast_module *mod);
+void ast_module_unref(struct ast_module *mod);
+
+struct ast_module *ast_module_ref(struct ast_module *mod)
+{
+ return __ast_module_ref(mod, __FILE__, __LINE__, __PRETTY_FUNCTION__);
+}
+
+void ast_module_unref(struct ast_module *mod)
+{
+ __ast_module_unref(mod, __FILE__, __LINE__, __PRETTY_FUNCTION__);
+}
More information about the asterisk-commits
mailing list