[svn-commits] rizzo: trunk r89031 - /trunk/main/loader.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Nov 6 11:05:13 CST 2007


Author: rizzo
Date: Tue Nov  6 11:05:13 2007
New Revision: 89031

URL: http://svn.digium.com/view/asterisk?view=rev&rev=89031
Log:
Fix embedding of modules on FreeBSD:
the constructor for the list of modules was run
after the constructors for the embedded modules
(which appended entries to the list).
As a result, the list appeared empty when it was
time to use it.

On linux the order of execution of constructor
was evidently different (it may depend on the
ordering of modules in the ELF file).

This is only a workaround - there may be other
situations where the execution of constructors
causes problems, so if we manage to find a more
general solution this workaround can go away.


Modified:
    trunk/main/loader.c

Modified: trunk/main/loader.c
URL: http://svn.digium.com/view/asterisk/trunk/main/loader.c?view=diff&rev=89031&r1=89030&r2=89031
==============================================================================
--- trunk/main/loader.c (original)
+++ trunk/main/loader.c Tue Nov  6 11:05:13 2007
@@ -95,6 +95,14 @@
 
 static AST_LIST_HEAD_STATIC(module_list, ast_module);
 
+/*
+ * module_list is cleared by its constructor possibly after
+ * we start accumulating embedded modules, so we need to
+ * use another list (without the lock) to accumulate them.
+ * Then we update the main list when embedding is done.
+ */
+static struct module_list embedded_module_list;
+
 struct loadupdate {
 	int (*updater)(void);
 	AST_LIST_ENTRY(loadupdate) entry;
@@ -133,18 +141,23 @@
 	   might be unsafe to use the list lock at that point... so
 	   let's avoid it altogether
 	*/
-	if (!embedding)
+	if (embedding) {
+		static int i;
+		fprintf(stderr, "---- embedding [%d] %p %p %s\n",
+			i++, embedded_module_list.first,
+			embedded_module_list.last,
+			info->name);
+		AST_LIST_INSERT_TAIL(&embedded_module_list, mod, entry);
+	} else {
 		AST_LIST_LOCK(&module_list);
-
-	/* it is paramount that the new entry be placed at the tail of
-	   the list, otherwise the code that uses dlopen() to load
-	   dynamic modules won't be able to find out if the module it
-	   just opened was registered or failed to load
-	*/
-	AST_LIST_INSERT_TAIL(&module_list, mod, entry);
-
-	if (!embedding)
+		/* it is paramount that the new entry be placed at the tail of
+		   the list, otherwise the code that uses dlopen() to load
+		   dynamic modules won't be able to find out if the module it
+		   just opened was registered or failed to load
+		*/
+		AST_LIST_INSERT_TAIL(&module_list, mod, entry);
 		AST_LIST_UNLOCK(&module_list);
+	}
 
 	/* give the module a copy of its own handle, for later use in registrations and the like */
 	*((struct ast_module **) &(info->self)) = mod;
@@ -746,6 +759,12 @@
 
 	AST_LIST_LOCK(&module_list);
 
+	if (embedded_module_list.first) {
+		module_list.first = embedded_module_list.first;
+		module_list.last = embedded_module_list.last;
+		embedded_module_list.first = NULL;
+	}
+
 	if (!(cfg = ast_config_load(AST_MODULE_CONFIG, config_flags))) {
 		ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
 		goto done;
@@ -900,7 +919,7 @@
 
 	if (AST_LIST_TRYLOCK(&module_list))
 		unlock = 0;
-
+ 
 	AST_LIST_TRAVERSE(&module_list, cur, entry) {
 		total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, like);
 	}




More information about the svn-commits mailing list