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.



git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@89031 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Luigi Rizzo
2007-11-06 17:05:13 +00:00
parent e9e78af981
commit 81456f8493

View File

@@ -95,6 +95,14 @@ struct ast_module {
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 @@ void ast_module_register(const struct ast_module_info *info)
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 @@ int load_modules(unsigned int preload_only)
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 @@ int ast_update_module_list(int (*modentry)(const char *module, const char *descr
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);
}