diff options
-rw-r--r-- | formats/format_g723.c | 5 | ||||
-rw-r--r-- | formats/format_g726.c | 5 | ||||
-rw-r--r-- | formats/format_g729.c | 5 | ||||
-rw-r--r-- | formats/format_gsm.c | 5 | ||||
-rw-r--r-- | formats/format_h263.c | 5 | ||||
-rw-r--r-- | formats/format_h264.c | 5 | ||||
-rw-r--r-- | formats/format_ilbc.c | 5 | ||||
-rw-r--r-- | formats/format_jpeg.c | 5 | ||||
-rw-r--r-- | formats/format_ogg_vorbis.c | 5 | ||||
-rw-r--r-- | formats/format_pcm.c | 5 | ||||
-rw-r--r-- | formats/format_sln.c | 5 | ||||
-rw-r--r-- | formats/format_vox.c | 5 | ||||
-rw-r--r-- | formats/format_wav.c | 5 | ||||
-rw-r--r-- | formats/format_wav_gsm.c | 5 | ||||
-rw-r--r-- | include/asterisk/module.h | 8 | ||||
-rw-r--r-- | main/loader.c | 118 |
16 files changed, 136 insertions, 60 deletions
diff --git a/formats/format_g723.c b/formats/format_g723.c index dd5a1e6af..c394b0f1e 100644 --- a/formats/format_g723.c +++ b/formats/format_g723.c @@ -160,4 +160,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, +); diff --git a/formats/format_g726.c b/formats/format_g726.c index 499d545d2..fbb7e4791 100644 --- a/formats/format_g726.c +++ b/formats/format_g726.c @@ -274,4 +274,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, +); diff --git a/formats/format_g729.c b/formats/format_g729.c index 3f46bcbff..a596c521c 100644 --- a/formats/format_g729.c +++ b/formats/format_g729.c @@ -156,4 +156,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, +); diff --git a/formats/format_gsm.c b/formats/format_gsm.c index 37fbd2382..9318fa3cf 100644 --- a/formats/format_gsm.c +++ b/formats/format_gsm.c @@ -180,4 +180,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, +); diff --git a/formats/format_h263.c b/formats/format_h263.c index baa7a3efd..7cbcc8d4e 100644 --- a/formats/format_h263.c +++ b/formats/format_h263.c @@ -194,4 +194,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, +); diff --git a/formats/format_h264.c b/formats/format_h264.c index bc70a75c7..70b9dd948 100644 --- a/formats/format_h264.c +++ b/formats/format_h264.c @@ -183,4 +183,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, +); diff --git a/formats/format_ilbc.c b/formats/format_ilbc.c index 659f42dbd..906ca9264 100644 --- a/formats/format_ilbc.c +++ b/formats/format_ilbc.c @@ -154,4 +154,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, +); diff --git a/formats/format_jpeg.c b/formats/format_jpeg.c index edef171d2..64c197a99 100644 --- a/formats/format_jpeg.c +++ b/formats/format_jpeg.c @@ -124,4 +124,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, +); diff --git a/formats/format_ogg_vorbis.c b/formats/format_ogg_vorbis.c index 7e20c0004..5a89098d6 100644 --- a/formats/format_ogg_vorbis.c +++ b/formats/format_ogg_vorbis.c @@ -568,5 +568,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, +); diff --git a/formats/format_pcm.c b/formats/format_pcm.c index a3deced7a..a1292e11f 100644 --- a/formats/format_pcm.c +++ b/formats/format_pcm.c @@ -504,4 +504,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, +); diff --git a/formats/format_sln.c b/formats/format_sln.c index c8c5cc04b..d085b131b 100644 --- a/formats/format_sln.c +++ b/formats/format_sln.c @@ -138,4 +138,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, +); diff --git a/formats/format_vox.c b/formats/format_vox.c index c729f3b5c..ef0697d33 100644 --- a/formats/format_vox.c +++ b/formats/format_vox.c @@ -143,4 +143,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, +); diff --git a/formats/format_wav.c b/formats/format_wav.c index de92e881e..38c0fc7a8 100644 --- a/formats/format_wav.c +++ b/formats/format_wav.c @@ -528,4 +528,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, +); diff --git a/formats/format_wav_gsm.c b/formats/format_wav_gsm.c index f82f9bc23..7e589bb88 100644 --- a/formats/format_wav_gsm.c +++ b/formats/format_wav_gsm.c @@ -559,4 +559,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, +); diff --git a/include/asterisk/module.h b/include/asterisk/module.h index 27eae4abe..7ea4e93a1 100644 --- a/include/asterisk/module.h +++ b/include/asterisk/module.h @@ -180,6 +180,14 @@ enum ast_module_flags { AST_MODFLAG_DEFAULT = 0, AST_MODFLAG_GLOBAL_SYMBOLS = (1 << 0), AST_MODFLAG_BUILDSUM = (1 << 1), + /*! + * \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 { diff --git a/main/loader.c b/main/loader.c index 3fd424d48..9190c743b 100644 --- a/main/loader.c +++ b/main/loader.c @@ -117,6 +117,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) @@ -339,13 +352,13 @@ 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[256]; void *lib; struct ast_module *mod; char *resource = (char *) resource_in; - unsigned int wants_global; + unsigned int wants_global = 0, not_yet = 0; if (strcasecmp(resource + strlen(resource) - 3, ".so")) { resource = alloca(strlen(resource_in) + 3); @@ -386,11 +399,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; } @@ -700,7 +724,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; @@ -711,13 +735,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 { @@ -832,6 +872,7 @@ int load_modules(unsigned int preload_only) unsigned int load_count; struct load_order load_order; int res = 0; + int load_pass; int translate_status; char newname[18]; /* although this would normally be 80, max length in translate_module_name is 18 */ @@ -941,43 +982,28 @@ 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: - case AST_MODULE_LOAD_DECLINE: - AST_LIST_REMOVE_CURRENT(&load_order, entry); - free(order->resource); - 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: - case AST_MODULE_LOAD_DECLINE: - AST_LIST_REMOVE_CURRENT(&load_order, entry); - free(order->resource); - 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: + case AST_MODULE_LOAD_DECLINE: + AST_LIST_REMOVE_CURRENT(&load_order, entry); + free(order->resource); + 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))) { |