[asterisk-commits] dlee: branch dlee/ASTERISK-22296 r397868 - in /team/dlee/ASTERISK-22296: ./ i...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Aug 28 15:25:36 CDT 2013


Author: dlee
Date: Wed Aug 28 15:25:34 2013
New Revision: 397868

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=397868
Log:
Check for RTLD_NOLOAD. Move checking to a more likely spot.

Modified:
    team/dlee/ASTERISK-22296/configure
    team/dlee/ASTERISK-22296/configure.ac
    team/dlee/ASTERISK-22296/include/asterisk/autoconfig.h.in
    team/dlee/ASTERISK-22296/main/loader.c

Modified: team/dlee/ASTERISK-22296/configure.ac
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/configure.ac?view=diff&rev=397868&r1=397867&r2=397868
==============================================================================
--- team/dlee/ASTERISK-22296/configure.ac (original)
+++ team/dlee/ASTERISK-22296/configure.ac Wed Aug 28 15:25:34 2013
@@ -1184,6 +1184,8 @@
 
 AST_C_DEFINE_CHECK([GLOB_BRACE], [GLOB_BRACE], [glob.h])
 
+AST_C_DEFINE_CHECK([RTLD_NOLOAD], [RTLD_NOLOAD], [dlfcn.h])
+
 AST_C_DEFINE_CHECK([IP_MTU_DISCOVER], [IP_MTU_DISCOVER], [netinet/in.h])
 
 AC_CHECK_HEADER([libkern/OSAtomic.h],

Modified: team/dlee/ASTERISK-22296/include/asterisk/autoconfig.h.in
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/include/asterisk/autoconfig.h.in?view=diff&rev=397868&r1=397867&r2=397868
==============================================================================
--- team/dlee/ASTERISK-22296/include/asterisk/autoconfig.h.in (original)
+++ team/dlee/ASTERISK-22296/include/asterisk/autoconfig.h.in Wed Aug 28 15:25:34 2013
@@ -728,6 +728,9 @@
 
 /* Define to 1 if you have the `roundl' function. */
 #undef HAVE_ROUNDL
+
+/* Define if your system has the RTLD_NOLOAD headers. */
+#undef HAVE_RTLD_NOLOAD
 
 /* Define to 1 if your system has /sbin/launchd. */
 #undef HAVE_SBIN_LAUNCHD

Modified: team/dlee/ASTERISK-22296/main/loader.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/main/loader.c?view=diff&rev=397868&r1=397867&r2=397868
==============================================================================
--- team/dlee/ASTERISK-22296/main/loader.c (original)
+++ team/dlee/ASTERISK-22296/main/loader.c Wed Aug 28 15:25:34 2013
@@ -418,6 +418,37 @@
 	}
 }
 
+#if defined(HAVE_RTLD_NOLOAD)
+/*!
+ * \brief Check to see if the given resource is loaded.
+ *
+ * \param resource_name Name of the resource, including .so suffix.
+ * \return False (0) if module is not loaded.
+ * \return True (non-zero) if module is loaded.
+ */
+static int is_module_loaded(const char *resource_name)
+{
+	char fn[PATH_MAX] = "";
+	void *lib;
+
+	ast_verb(10, "Checking if %s is loaded\n", resource_name);
+
+	snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_MODULE_DIR,
+		resource_name);
+
+	lib = dlopen(fn, RTLD_LAZY | RTLD_NOLOAD);
+
+	if (lib) {
+		ast_verb(10, "  %s loaded\n", resource_name);
+		logged_dlclose(resource_name, lib);
+		return 1;
+	}
+
+	ast_verb(10, "  %s not loaded\n", resource_name);
+	return 0;
+}
+#endif
+
 static void unload_dynamic_module(struct ast_module *mod)
 {
 	char *name = ast_strdupa(ast_module_name(mod));
@@ -427,8 +458,31 @@
 	   disappear when this operation succeeds, so we can't
 	   dereference it */
 
-	if (lib)
-		logged_dlclose(name, lib);
+	if (!lib) {
+		return;
+	}
+
+	logged_dlclose(name, lib);
+
+	/* There are several situations where the module might still be resident
+	 * in memory.
+	 *
+	 * If somehow there was another dlopen() on the same module (unlikely,
+	 * since that all is supposed to happen in loader.c).
+	 *
+	 * Or the lazy resolution of a global symbol (very likely, since that is
+	 * how we load all of our modules that export global symbols).
+	 *
+	 * Avoid the temptation of repeating the dlclose(). The other code that
+	 * dlopened the module still has its module reference, and should close
+	 * it itself. In other situations, dlclose() will happily return success
+	 * for as many times as you wish to call it.
+	 */
+#if defined(HAVE_RTLD_NOLOAD)
+	if (is_module_loaded(name)) {
+		ast_log(LOG_WARNING, "Module '%s' could not be completely unloaded\n", name);
+	}
+#endif
 }
 
 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap, int required);
@@ -519,36 +573,6 @@
 	return AST_LIST_LAST(&module_list);
 }
 
-/*!
- * \brief Check to see if the given resource is loaded.
- *
- * \param resource_name Name of the resource, optionally with .so.
- * \return False (0) if module is not loaded.
- * \return True (non-zero) if module is loaded.
- */
-static int is_module_loaded(const char *resource_name)
-{
-	char fn[PATH_MAX] = "";
-	int missing_so = 0;
-	void *lib;
-
-	if (strcasecmp(resource_name + strlen(resource_name) - 3, ".so")) {
-		missing_so = 1;
-	}
-
-	snprintf(fn, sizeof(fn), "%s/%s%s", ast_config_AST_MODULE_DIR,
-		resource_name, missing_so ? ".so" : "");
-
-	lib = dlopen(fn, RTLD_LAZY | RTLD_NOLOAD);
-
-	if (lib) {
-		logged_dlclose(resource_name, lib);
-		return 1;
-	}
-
-	return 0;
-}
-
 #endif
 
 void ast_module_shutdown(void)
@@ -656,9 +680,6 @@
 #ifdef LOADABLE_MODULES
 	if (!error) {
 		unload_dynamic_module(mod);
-		if (is_module_loaded(resource_name)) {
-			ast_log(LOG_WARNING, "Module '%s' could not be completely unloaded\n", resource_name);
-		}
 		ast_test_suite_event_notify("MODULE_UNLOAD", "Message: %s", resource_name);
 	}
 #endif




More information about the asterisk-commits mailing list