]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Set a module load priority for format modules.
authorRussell Bryant <russell@russellbryant.com>
Wed, 9 Dec 2009 15:28:59 +0000 (15:28 +0000)
committerRussell Bryant <russell@russellbryant.com>
Wed, 9 Dec 2009 15:28:59 +0000 (15:28 +0000)
A recent change to app_voicemail made it such that the module now assumes that
all format modules are available while processing voicemail configuration.
However, when autoloading modules, it was possible that app_voicemail was
loaded before the format modules. Since format modules don't depend on
anything, set a module load priority on them to ensure that they get loaded
first when autoloading.

This version of the patch is specific to Asterisk 1.4 and 1.6.0.  These versions
did not already support module load priority in the module API.  This adds a
trivial version of this which is just a module flag to include it in a pass before
loading "everything".

Thanks to mmichelson for the review!

(closes issue #16412)
Reported by: jiddings
Tested by: russell

Review: https://reviewboard.asterisk.org/r/445/

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.0@233841 65c4cc65-6c06-0410-ace0-fbb531ad65f3

17 files changed:
formats/format_g723.c
formats/format_g726.c
formats/format_g729.c
formats/format_gsm.c
formats/format_h263.c
formats/format_h264.c
formats/format_ilbc.c
formats/format_jpeg.c
formats/format_ogg_vorbis.c
formats/format_pcm.c
formats/format_sln.c
formats/format_sln16.c
formats/format_vox.c
formats/format_wav.c
formats/format_wav_gsm.c
include/asterisk/module.h
main/loader.c

index 6e57b4fa8561af76e23492c84d174865e06cc0e9..8580631f9c245d8e20b2f102e768a39a29dcdce7 100644 (file)
@@ -149,4 +149,7 @@ static int unload_module(void)
        return ast_format_unregister(g723_1_f.name);
 }      
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "G.723.1 Simple Timestamp File Format");
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_FIRST, "G.723.1 Simple Timestamp File Format",
+       .load = load_module,
+       .unload = unload_module,
+);
index e27476fedd9d8243f6ee4c70d74e892048897204..c8b6233da04b9d9bebbfa64efaff83392bb34342 100644 (file)
@@ -258,4 +258,7 @@ static int unload_module(void)
        return(0);
 }      
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw G.726 (16/24/32/40kbps) data");
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_FIRST, "Raw G.726 (16/24/32/40kbps) data",
+       .load = load_module,
+       .unload = unload_module,
+);
index 8df463d81a3f38e27e85288592cfc1755ffd00bf..09a9caba4e8fa182c51a04ac9cac0ec33f2e7525 100644 (file)
@@ -145,4 +145,7 @@ static int unload_module(void)
        return ast_format_unregister(g729_f.name);
 }      
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw G729 data");
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_FIRST, "Raw G729 data",
+       .load = load_module,
+       .unload = unload_module,
+);
index d8a0813b65ab5c0a680911177309fe61b89b9cfd..073d5d6063f13e96f13929786aa0248dc01e5f93 100644 (file)
@@ -169,4 +169,7 @@ static int unload_module(void)
        return ast_format_unregister(gsm_f.name);
 }      
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw GSM data");
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_FIRST, "Raw GSM data",
+       .load = load_module,
+       .unload = unload_module,
+);
index b0b5cb27db92437fa63ed0fdaacd281936b1b1b7..709f3c2ffe6ad0bb2109e1fe0d232ca83aa0a72d 100644 (file)
@@ -183,4 +183,7 @@ static int unload_module(void)
        return ast_format_unregister(h263_f.name);
 }      
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw H.263 data");
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_FIRST, "Raw H.263 data",
+       .load = load_module,
+       .unload = unload_module,
+);
index 06def313cd93c4a6363bf88c58835d612cdc0475..2d09177a81ba2b63dbfc42f26fd2ed233bac632e 100644 (file)
@@ -172,4 +172,7 @@ static int unload_module(void)
        return ast_format_unregister(h264_f.name);
 }      
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw H.264 data");
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_FIRST, "Raw H.264 data",
+       .load = load_module,
+       .unload = unload_module,
+);
index fac2149bc974e94e3439ab9198b2dd578c3c98f2..1f0b8ce0bfc8f42bc19c3bacce8eb03829e63f34 100644 (file)
@@ -143,4 +143,7 @@ static int unload_module(void)
        return ast_format_unregister(ilbc_f.name);
 }      
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw iLBC data");
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_FIRST, "Raw iLBC data",
+       .load = load_module,
+       .unload = unload_module,
+);
index 4d8d7855d4cd8687a3f398110dcc3d25b8f38ecf..3613b364fb1b6da69a4a24b6a713102bb21cefa4 100644 (file)
@@ -112,4 +112,7 @@ static int unload_module(void)
        return 0;
 }      
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "JPEG (Joint Picture Experts Group) Image Format");
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_FIRST, "JPEG (Joint Picture Experts Group) Image Format",
+       .load = load_module,
+       .unload = unload_module,
+);
index c2dc977b6c0f57a4f9ee0a73594cca6615878170..ea36a7c67caab9a86113d7fbffb768db49354608 100644 (file)
@@ -556,5 +556,8 @@ static int unload_module(void)
        return ast_format_unregister(vorbis_f.name);
 }
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "OGG/Vorbis audio");
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_FIRST, "OGG/Vorbis audio",
+       .load = load_module,
+       .unload = unload_module,
+);
 
index a9c44d5026da8526b167c940df76cce11cad09a5..1530a5dc92caeeca0c171293ddeed5e23697b69e 100644 (file)
@@ -494,4 +494,7 @@ static int unload_module(void)
                || ast_format_unregister(g722_f.name);
 }      
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw/Sun uLaw/ALaw 8KHz (PCM,PCMA,AU), G.722 16Khz");
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_FIRST, "Raw/Sun uLaw/ALaw 8KHz (PCM,PCMA,AU), G.722 16Khz",
+       .load = load_module,
+       .unload = unload_module,
+);
index 51f796271ee3a9b018b986ee908abe9506ef17ca..212b203783a7daec1f196de546533340aad50c17 100644 (file)
@@ -127,4 +127,7 @@ static int unload_module(void)
        return ast_format_unregister(slin_f.name);
 }      
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw Signed Linear Audio support (SLN)");
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_FIRST, "Raw Signed Linear Audio support (SLN)",
+       .load = load_module,
+       .unload = unload_module,
+);
index 50349f2dd9e094dde73468277e949703aecd6952..6cdd392be9cf4aa8f889e416e610f0e58608bc23 100644 (file)
@@ -135,4 +135,7 @@ static int unload_module(void)
        return ast_format_unregister(slin_f.name);
 }      
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw Signed Linear 16KHz Audio support (SLN16)");
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_FIRST, "Raw Signed Linear 16KHz Audio support (SLN16)",
+       .load = load_module,
+       .unload = unload_module,
+);
index f22b4881a850a656291a403607f3311469f58ca1..9bb76de26478ce0f2068cc128b388efc4c7515fe 100644 (file)
@@ -132,4 +132,7 @@ static int unload_module(void)
        return ast_format_unregister(vox_f.name);
 }      
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialogic VOX (ADPCM) File Format");
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_FIRST, "Dialogic VOX (ADPCM) File Format",
+       .load = load_module,
+       .unload = unload_module,
+);
index 94980477aec7a55a93fe25e135baacbd643326de..3a43c39bcda52518d436e8a6ff7e3f8b151f5e2f 100644 (file)
@@ -491,4 +491,7 @@ static int unload_module(void)
        return ast_format_unregister(wav_f.name);
 }      
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Microsoft WAV format (8000Hz Signed Linear)");
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_FIRST, "Microsoft WAV format (8000Hz Signed Linear)",
+       .load = load_module,
+       .unload = unload_module,
+);
index 9c71c591ec348ccf6219a69afe897c468b3b94a7..7c63d280f3e017b9ef4fc5016e5894b4e2baf7e1 100644 (file)
@@ -548,4 +548,7 @@ static int unload_module(void)
        return ast_format_unregister(wav49_f.name);
 }      
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Microsoft WAV format (Proprietary GSM)");
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_FIRST, "Microsoft WAV format (Proprietary GSM)",
+       .load = load_module,
+       .unload = unload_module,
+);
index a46f3319cb64f9645e1d1f703a848de4ef1bf46d..2e308bc79e9ae27dbf652627660d2b5d218543ec 100644 (file)
@@ -189,6 +189,14 @@ struct ast_module_user_list;
 enum ast_module_flags {
        AST_MODFLAG_DEFAULT = 0,
        AST_MODFLAG_GLOBAL_SYMBOLS = (1 << 0),
+       /*!
+        * \brief Load this module in the first pass on auto loading
+        *
+        * When module auto loading is used, modules with this flag set will
+        * be loaded after preloaded modules, but before all modules being
+        * automatically loaded without this flag set on them.
+        */
+       AST_MODFLAG_LOAD_FIRST = (1 << 2),
 };
 
 struct ast_module_info {
index 0772db14c2837503fa53cc41173a3ffed2e4a269..2a7d356157e14db38cf3ffc00df57ec98b449556 100644 (file)
@@ -125,6 +125,19 @@ static AST_LIST_HEAD_STATIC(reload_queue, reload_queue_item);
 */
 struct ast_module *resource_being_loaded;
 
+/*! \brief Load modules in this order. */
+enum module_load_pass {
+       /*! \brief AST_MODFLAG_LOAD_FIRST */
+       LOAD_FIRST,
+       /*! \brief AST_MODFLAG_GLOBAL_SYMBOLS */
+       LOAD_GLOBAL_SYMBOLS,
+       /*! \brief everything that is left */
+       LOAD_ALL,
+
+       /*! \brief Must remain at the end. */
+       LOAD_DONE,
+};
+
 /* XXX: should we check for duplicate resource names here? */
 
 void ast_module_register(const struct ast_module_info *info)
@@ -348,12 +361,12 @@ static void unload_dynamic_module(struct ast_module *mod)
                while (!dlclose(lib));
 }
 
-static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int global_symbols_only)
+static struct ast_module *load_dynamic_module(const char *resource_in, enum module_load_pass load_pass)
 {
        char fn[PATH_MAX] = "";
        void *lib = NULL;
        struct ast_module *mod;
-       unsigned int wants_global;
+       unsigned int wants_global = 0, not_yet = 0;
        int space;      /* room needed for the descriptor */
        int missing_so = 0;
 
@@ -398,11 +411,22 @@ static struct ast_module *load_dynamic_module(const char *resource_in, unsigned
                return NULL;
        }
 
-       wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS);
+       switch (load_pass) {
+       case LOAD_FIRST:
+               not_yet = !ast_test_flag(mod->info, AST_MODFLAG_LOAD_FIRST);
+               break;
+       case LOAD_GLOBAL_SYMBOLS:
+               wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS);
+               not_yet = !wants_global;
+               break;
+       case LOAD_ALL:
+               break;
+       case LOAD_DONE:
+               ast_log(LOG_ERROR, "Satan just bought a snowblower! (This should never happen, btw.)\n");
+               break;
+       }
 
-       /* if we are being asked only to load modules that provide global symbols,
-          and this one does not, then close it and return */
-       if (global_symbols_only && !wants_global) {
+       if (not_yet) {
                while (!dlclose(lib));
                return NULL;
        }
@@ -709,7 +733,7 @@ static unsigned int inspect_module(const struct ast_module *mod)
        return 0;
 }
 
-static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only)
+static enum ast_module_load_result load_resource(const char *resource_name, enum module_load_pass load_pass)
 {
        struct ast_module *mod;
        enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
@@ -720,13 +744,29 @@ static enum ast_module_load_result load_resource(const char *resource_name, unsi
                        ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name);
                        return AST_MODULE_LOAD_DECLINE;
                }
-               if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS))
-                       return AST_MODULE_LOAD_SKIP;
+
+               switch (load_pass) {
+               case LOAD_FIRST:
+                       if (!ast_test_flag(mod->info, AST_MODFLAG_LOAD_FIRST)) {
+                               return AST_MODULE_LOAD_SKIP;
+                       }
+                       break;
+               case LOAD_GLOBAL_SYMBOLS:
+                       if (!ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS)) {
+                               return AST_MODULE_LOAD_SKIP;
+                       }
+                       break;
+               case LOAD_ALL:
+                       break;
+               case LOAD_DONE:
+                       ast_log(LOG_ERROR, "This should never happen, -EFLAMES!\n");
+                       break;
+               }
        } else {
 #ifdef LOADABLE_MODULES
-               if (!(mod = load_dynamic_module(resource_name, global_symbols_only))) {
+               if (!(mod = load_dynamic_module(resource_name, load_pass))) {
                        /* don't generate a warning message during load_modules() */
-                       if (!global_symbols_only) {
+                       if (load_pass == LOAD_ALL) {
                                ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
                                return AST_MODULE_LOAD_DECLINE;
                        } else {
@@ -830,6 +870,7 @@ int load_modules(unsigned int preload_only)
        int res = 0;
        struct ast_flags config_flags = { 0 };
        int modulecount = 0;
+       int load_pass;
 
 #ifdef LOADABLE_MODULES
        struct dirent *dirent;
@@ -936,45 +977,29 @@ int load_modules(unsigned int preload_only)
        if (load_count)
                ast_log(LOG_NOTICE, "%d modules will be loaded.\n", load_count);
 
-       /* first, load only modules that provide global symbols */
-       AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
-               switch (load_resource(order->resource, 1)) {
-               case AST_MODULE_LOAD_SUCCESS:
-                       modulecount++;
-               case AST_MODULE_LOAD_DECLINE:
-                       AST_LIST_REMOVE_CURRENT(entry);
-                       ast_free(order->resource);
-                       ast_free(order);
-                       break;
-               case AST_MODULE_LOAD_FAILURE:
-                       res = -1;
-                       goto done;
-               case AST_MODULE_LOAD_SKIP:
-                       /* try again later */
-                       break;
-               }
-       }
-       AST_LIST_TRAVERSE_SAFE_END;
-
-       /* now load everything else */
-       AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
-               switch (load_resource(order->resource, 0)) {
-               case AST_MODULE_LOAD_SUCCESS:
-                       modulecount++;
-               case AST_MODULE_LOAD_DECLINE:
-                       AST_LIST_REMOVE_CURRENT(entry);
-                       ast_free(order->resource);
-                       ast_free(order);
-                       break;
-               case AST_MODULE_LOAD_FAILURE:
-                       res = -1;
-                       goto done;
-               case AST_MODULE_LOAD_SKIP:
-                       /* should not happen */
-                       break;
+       for (load_pass = 0; load_pass < LOAD_DONE; load_pass++) {
+               AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
+                       switch (load_resource(order->resource, load_pass)) {
+                       case AST_MODULE_LOAD_SUCCESS:
+                               modulecount++;
+                       case AST_MODULE_LOAD_DECLINE:
+                               AST_LIST_REMOVE_CURRENT(entry);
+                               ast_free(order->resource);
+                               ast_free(order);
+                               break;
+                       case AST_MODULE_LOAD_FAILURE:
+                               res = -1;
+                               goto done;
+                       case AST_MODULE_LOAD_SKIP:
+                               /* 
+                                * Try again later. This result is received when a module is
+                                * deferred because it is not a part of the current pass. 
+                                */
+                               break;
+                       }
                }
+               AST_LIST_TRAVERSE_SAFE_END;
        }
-       AST_LIST_TRAVERSE_SAFE_END;
 
 done:
        while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {