[asterisk-dev] ugly fix for module embedding bug (Re: module embedding help ?)
Luigi Rizzo
rizzo at icir.org
Tue Nov 6 09:52:01 CST 2007
I found the bug that causes module embedding not to work on FreeBSD
(and maybe on other architectures too).
Module embedding is implemented using some linker magic that
causes ast_module_register() to be called for each of the
embedded objects.
This in turn adds the entry to a list, module_list, in main/loader.c
The problem is that module_list itself has a constructor associated:
static AST_LIST_HEAD_STATIC(module_list, ast_module);
which happens (at least on FreeBSD) to be called _after_ the
other constructors. The constructor resets module_list to
empty, so you can imagine the result.
I have an ugly fix, below - store the relevant values from
module_list in a static variable not subject to constructors,
and restore module_list from that variable near the beginning
of load_modules().
However i don't like it too much, and furthermore I am afraid that
the same problem - unspecified order in the execution of
constructors - may appear also in other parts of the code.
Anyways, if you think it is ok to commit this one i will do
as a temporary bandaid.
cheers
luigi
Index: main/loader.c
===================================================================
--- main/loader.c (revision 88929)
+++ main/loader.c (working copy)
@@ -110,6 +110,10 @@
*/
struct ast_module *resource_being_loaded;
+static struct _mine {
+ void *modlist_first;
+ void *modlist_last;
+} mine;
/* XXX: should we check for duplicate resource names here? */
void ast_module_register(const struct ast_module_info *info)
@@ -142,6 +156,10 @@
just opened was registered or failed to load
*/
AST_LIST_INSERT_TAIL(&module_list, mod, entry);
+ if (embedding) {
+ mine.modlist_first = module_list.first;
+ mine.modlist_last = module_list.last;
+ }
if (!embedding)
AST_LIST_UNLOCK(&module_list);
@@ -738,6 +755,11 9@@
AST_LIST_HEAD_INIT_NOLOCK(&load_order);
AST_LIST_LOCK(&module_list);
+ if (mine.modlist_first) {
+ module_list.first = mine.modlist_first;
+ module_list.last = mine.modlist_last;
+ mine.modlist_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;
More information about the asterisk-dev
mailing list