]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
improve loader a bit, by avoiding trying to initialize embedded modules twice and...
authorKevin P. Fleming <kpfleming@digium.com>
Thu, 3 May 2007 16:38:56 +0000 (16:38 +0000)
committerKevin P. Fleming <kpfleming@digium.com>
Thu, 3 May 2007 16:38:56 +0000 (16:38 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@62986 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/loader.c

index d0fb2e33a3d44a8ae395c77d9c93b56b105584c1..012f0e810d3bf12621860946e104587435534a5f 100644 (file)
@@ -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];
 };
@@ -442,7 +440,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 (!mod->lib) {
@@ -475,7 +473,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);
 
@@ -552,7 +550,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 */
@@ -600,7 +598,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;
                }
@@ -631,7 +629,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();
@@ -648,12 +646,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;
@@ -719,18 +717,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"))
@@ -739,9 +734,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
@@ -756,10 +759,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);
@@ -842,6 +849,8 @@ done:
                free(order);
        }
 
+       AST_LIST_UNLOCK(&module_list);
+
        return res;
 }