diff --git a/main/loader.c b/main/loader.c index e167f474efe5fa5346ab0ab759410e7f6b22daae..d9530f4d2e18ac09481e90ea903223133c4cf08b 100644 --- a/main/loader.c +++ b/main/loader.c @@ -80,17 +80,15 @@ static unsigned int embedding = 1; /* we always start out by registering embedde since they are here before we dlopen() any */ -enum flags { - FLAG_RUNNING = (1 << 1), /* module successfully initialized */ - FLAG_DECLINED = (1 << 2), /* module declined to initialize */ -}; - struct ast_module { const struct ast_module_info *info; 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 */ - unsigned int flags; /* flags for this module */ + struct { + unsigned int running:1; + unsigned int declined:1; + } flags; AST_LIST_ENTRY(ast_module) entry; char resource[0]; }; @@ -443,7 +441,7 @@ int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode f return 0; } - if (!ast_test_flag(mod, FLAG_RUNNING | FLAG_DECLINED)) + if (!(mod->flags.running || mod->flags.declined)) error = 1; if (!error && (mod->usecount > 0)) { @@ -471,7 +469,7 @@ int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode f } if (!error) - ast_clear_flag(mod, FLAG_RUNNING | FLAG_DECLINED); + mod->flags.running = mod->flags.declined = 0; AST_LIST_UNLOCK(&module_list); @@ -551,7 +549,7 @@ int ast_module_reload(const char *name) if (name && resource_name_match(name, cur->resource)) continue; - if (!ast_test_flag(cur, FLAG_RUNNING | FLAG_DECLINED)) + if (!(cur->flags.running || cur->flags.declined)) continue; if (!info->reload) { /* cannot be reloaded */ @@ -599,7 +597,7 @@ static enum ast_module_load_result load_resource(const char *resource_name, unsi char tmp[256]; if ((mod = find_resource(resource_name, 0))) { - if (ast_test_flag(mod, FLAG_RUNNING)) { + if (mod->flags.running) { ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name); return AST_MODULE_LOAD_DECLINE; } @@ -635,7 +633,7 @@ static enum ast_module_load_result load_resource(const char *resource_name, unsi return AST_MODULE_LOAD_DECLINE; } - ast_clear_flag(mod, FLAG_DECLINED); + mod->flags.declined = 0; if (mod->info->load) res = mod->info->load(); @@ -652,12 +650,12 @@ static enum ast_module_load_result load_resource(const char *resource_name, unsi ast_verbose(VERBOSE_PREFIX_1 "Loaded %s => (%s)\n", resource_name, mod->info->description); } - ast_set_flag(mod, FLAG_RUNNING); + mod->flags.running = 1; ast_update_use_count(); break; case AST_MODULE_LOAD_DECLINE: - ast_set_flag(mod, FLAG_DECLINED); + mod->flags.declined = 1; break; case AST_MODULE_LOAD_FAILURE: break; @@ -723,18 +721,15 @@ int load_modules(unsigned int preload_only) if (option_verbose) ast_verbose("Asterisk Dynamic Loader Starting:\n"); - AST_LIST_TRAVERSE(&module_list, mod, entry) { - if (option_debug > 1) - ast_log(LOG_DEBUG, "Embedded module found: %s\n", mod->resource); - } + AST_LIST_HEAD_INIT_NOLOCK(&load_order); + + AST_LIST_LOCK(&module_list); if (!(cfg = ast_config_load(AST_MODULE_CONFIG))) { ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG); - return 0; + goto done; } - AST_LIST_HEAD_INIT_NOLOCK(&load_order); - /* first, find all the modules we have been explicitly requested to load */ for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) { if (!strcasecmp(v->name, preload_only ? "preload" : "load")) @@ -743,9 +738,17 @@ int load_modules(unsigned int preload_only) /* check if 'autoload' is on */ if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) { - /* if so, first add all the embedded modules to the load order */ - AST_LIST_TRAVERSE(&module_list, mod, entry) + /* if so, first add all the embedded modules that are not already running to the load order */ + AST_LIST_TRAVERSE(&module_list, mod, entry) { + /* if it's not embedded, skip it */ + if (mod->lib) + continue; + + if (mod->flags.running) + continue; + order = add_to_load_order(mod->resource, &load_order); + } #if LOADABLE_MODULES /* if we are allowed to load dynamic modules, scan the directory for @@ -760,10 +763,14 @@ int load_modules(unsigned int preload_only) continue; if (strcasecmp(dirent->d_name + ld - 3, ".so")) - continue; + continue; - add_to_load_order(dirent->d_name, &load_order); + /* if there is already a module by this name in the module_list, + skip this file */ + if (find_resource(dirent->d_name, 0)) + continue; + add_to_load_order(dirent->d_name, &load_order); } closedir(dir); @@ -846,6 +853,8 @@ done: free(order); } + AST_LIST_UNLOCK(&module_list); + return res; }