aboutsummaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
authorkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2006-08-23 19:28:13 +0000
committerkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2006-08-23 19:28:13 +0000
commit6d8a5523b31d7d9afd03b33f435b8d2177486728 (patch)
treed7e82edc8e2c978bd2edf5b9b81c8639d8fb92fd /main
parent5b8099887a4f788aa49072c99eea808f4e1f3dc4 (diff)
use RTLD_NOLOAD if it's available to make loading dynamic modules a little faster and less resource-intensive
also, keep trying to dlclose() a module until it actually goes away, since it may have other modules it brought in when it was loaded (thanks PCadach for pointing this problem out to me) git-svn-id: http://svn.digium.com/svn/asterisk/trunk@40949 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main')
-rw-r--r--main/loader.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/main/loader.c b/main/loader.c
index 4d8e527f3..a4cf7a825 100644
--- a/main/loader.c
+++ b/main/loader.c
@@ -324,7 +324,7 @@ static struct ast_module *find_resource(const char *resource, int do_lock)
static void unload_dynamic_module(struct ast_module *mod)
{
if (mod->lib)
- dlclose(mod->lib);
+ while (!dlclose(mod->lib));
/* WARNING: the structure pointed to by mod is now gone! */
}
@@ -368,7 +368,7 @@ static struct ast_module *load_dynamic_module(const char *resource_in, unsigned
*/
if (resource_being_loaded != (mod = AST_LIST_LAST(&module_list))) {
/* no, it did not, so close it and return */
- dlclose(lib);
+ while (!dlclose(lib));
/* note that the module's destructor will call ast_module_unregister(),
which will free the structure we allocated in resource_being_loaded */
return NULL;
@@ -376,15 +376,27 @@ static struct ast_module *load_dynamic_module(const char *resource_in, unsigned
wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS);
- /* we are done with this first load, so clean up and start over */
-
- dlclose(lib);
- resource_being_loaded = NULL;
-
/* 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 (global_symbols_only && !wants_global) {
+ while (!dlclose(lib));
+ return NULL;
+ }
+
+ /* if the system supports RTLD_NOLOAD, we can just 'promote' the flags
+ on the already-opened library to what we want... if not, we have to
+ close it and start over
+ */
+#if HAVE_RTLD_NOLOAD
+ if (!dlopen(fn, RTLD_NOLOAD | (wants_global ? RTLD_GLOBAL : RTLD_NOW))) {
+ ast_log(LOG_WARNING, "%s\n", dlerror());
+ while (!dlclose(lib));
+ free(resource_being_loaded);
return NULL;
+ }
+#else
+ while (!dlclose(lib));
+ resource_being_loaded = NULL;
/* start the load process again */
@@ -402,6 +414,8 @@ static struct ast_module *load_dynamic_module(const char *resource_in, unsigned
/* since the module was successfully opened, and it registered itself
the previous time we did that, we're going to assume it worked this
time too :) */
+#endif
+
AST_LIST_LAST(&module_list)->lib = lib;
resource_being_loaded = NULL;