diff --git a/include/asterisk/module.h b/include/asterisk/module.h index b00ec488d1d16de5f207256a770bd6825ce20f6a..5e1b6e0946f345dc83f578fe5944f2e1fcd0da56 100644 --- a/include/asterisk/module.h +++ b/include/asterisk/module.h @@ -34,12 +34,12 @@ extern "C" { #endif -#ifndef STATIC_MODULE -#define STATIC_MODULE /* empty - symbols are global */ -#else +#ifdef STATIC_MODULE /* symbols are static */ +#define _HAVE_STATIC_MODULE #undef STATIC_MODULE #define STATIC_MODULE static /* symbols are static */ -#endif +#else /* !STATIC_MODULE, symbols are global */ +#define STATIC_MODULE /* empty - symbols are global */ /*! \note Every module should provide these functions */ /*! @@ -53,7 +53,7 @@ extern "C" { * If the module is not loaded successfully, Asterisk will call its * unload_module() function. */ -STATIC_MODULE int load_module(void); +int load_module(void); /*! * \brief Cleanup all module structures, sockets, etc. @@ -64,7 +64,7 @@ STATIC_MODULE int load_module(void); * * \return Zero on success, or non-zero on error. */ -STATIC_MODULE int unload_module(void); +int unload_module(void); /*! * \brief Provides a usecount. @@ -76,13 +76,13 @@ STATIC_MODULE int unload_module(void); * * \return The module's usecount. */ -STATIC_MODULE int usecount(void); /* How many channels provided by this module are in use? */ +int usecount(void); /* How many channels provided by this module are in use? */ /*! \brief Provides a description of the module. * * \return a short description of your module */ -STATIC_MODULE char *description(void); /* Description of this module */ +char *description(void); /* Description of this module */ /*! * \brief Returns the ASTERISK_GPL_KEY @@ -99,7 +99,7 @@ STATIC_MODULE char *description(void); /* Description of this module */ * * \return ASTERISK_GPL_KEY */ -STATIC_MODULE char *key(void); /* Return the below mentioned key, unmodified */ +char *key(void); /* Return the below mentioned key, unmodified */ /*! * \brief Reload stuff. @@ -109,7 +109,8 @@ STATIC_MODULE char *key(void); /* Return the below mentioned key, unmodified */ * * \return The return value is not used. */ -STATIC_MODULE int reload(void); /* reload configs */ +int reload(void); /* reload configs */ +#endif /* !STATIC_MODULE case */ /*! \brief The text the key() function should return. */ #define ASTERISK_GPL_KEY \ @@ -506,6 +507,15 @@ struct symbol_entry { #define MOD_FIELD(f) . ## f = f #define METHOD_BASE(_base, _name) . ## _name = _base ## _name +/* + * Each 'registerable' entity has a pointer in the + * struct ast_registry, which points to an array of objects of + * the same type. The ast_*_register() function will be able to + * derive the size of these entries. + */ +struct ast_registry { + struct ast_cli_entry *clis; +}; struct module_symbols { int (*load_module)(void); @@ -520,22 +530,27 @@ struct module_symbols { MOD_1, /* old style, but symbols here */ MOD_2, /* new style, exported symbols */ } type; + struct ast_registry *reg; struct symbol_entry *exported_symbols; struct symbol_entry *required_symbols; }; -#define STD_MOD(t, exp, req) \ +#ifndef _HAVE_STATIC_MODULE +#define STD_MOD(t, reload_fn, exp, req) +#else +#define STD_MOD(t, reload_fn, exp, req) \ struct module_symbols mod_data = { \ .load_module = load_module, \ .unload_module = unload_module, \ .description = description, \ .key = key, \ - .reload = reload, \ + .reload = reload_fn, \ .usecount = usecount, \ .type = t, \ .exported_symbols = exp, \ .required_symbols = req \ }; +#endif /* _HAVE_STATIC_MODULE */ #if defined(__cplusplus) || defined(c_plusplus) } diff --git a/loader.c b/loader.c index d467528a5c50acf9fea735b2009615ab4ed023f4..08dca973a34f0ef45e6fe42550a72b99f7ea102c 100644 --- a/loader.c +++ b/loader.c @@ -683,26 +683,20 @@ static struct module * __load_resource(const char *resource_name, int res; struct module *cur; struct module_symbols *m, *m1; - int flags=RTLD_NOW; + int flags = RTLD_NOW; unsigned char *key; char tmp[80]; - if (strncasecmp(resource_name, "res_", 4)) { -#ifdef RTLD_GLOBAL - if (cfg) { - char *val; - if ((val = ast_variable_retrieve(cfg, "global", resource_name)) - && ast_true(val)) - flags |= RTLD_GLOBAL; - } +#ifndef RTLD_GLOBAL +#define RTLD_GLOBAL 0 /* so it is a No-op */ #endif + if (strncasecmp(resource_name, "res_", 4) && cfg) { + char *val = ast_variable_retrieve(cfg, "global", resource_name); + if (val && ast_true(val)) + flags |= RTLD_GLOBAL; } else { /* Resource modules are always loaded global and lazy */ -#ifdef RTLD_GLOBAL flags = (RTLD_GLOBAL | RTLD_LAZY); -#else - flags = RTLD_LAZY; -#endif } if (AST_LIST_LOCK(&module_list)) @@ -722,16 +716,19 @@ static struct module * __load_resource(const char *resource_name, ast_copy_string(fn, resource_name, sizeof(fn)); else snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_MODULE_DIR, resource_name); -#if 0 - /* XXX test, open in a sane way */ + + /* open in a sane way */ cur->lib = dlopen(fn, RTLD_NOW | RTLD_LOCAL); if (cur->lib == NULL) { - ast_log(LOG_WARNING, "test %s\n", dlerror()); - } else + ast_log(LOG_WARNING, "cannot load %s %s\n", fn, dlerror()); + } else if ( (m1 = find_symbol(cur, "mod_data", 0)) == NULL || m1->type == MOD_0) { + /* old-style module, close and reload with standard flags */ dlclose(cur->lib); -#endif + cur->lib = NULL; + } + if (cur->lib == NULL) /* try reopen with the old style */ + cur->lib = dlopen(fn, flags); - cur->lib = dlopen(fn, flags); if (!cur->lib) { ast_log(LOG_WARNING, "%s\n", dlerror()); free(cur); @@ -740,10 +737,10 @@ static struct module * __load_resource(const char *resource_name, } m1 = find_symbol(cur, "mod_data", 0); if (m1 != NULL) { /* new style module */ + ast_log(LOG_WARNING, "new style %s (%d) loaded RTLD_LOCAL\n", + resource_name, m1->type); errors = check_exported(cur); *m = *m1; - if (m->type == MOD_2) - ast_log(LOG_WARNING, "new style %s, should unload and reload with RTLD_LOCAL\n", resource_name); } else { m->type = MOD_0; m->load_module = find_symbol(cur, "load_module", 1);