diff options
author | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-08-23 19:28:13 +0000 |
---|---|---|
committer | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-08-23 19:28:13 +0000 |
commit | 6d8a5523b31d7d9afd03b33f435b8d2177486728 (patch) | |
tree | d7e82edc8e2c978bd2edf5b9b81c8639d8fb92fd /main/loader.c | |
parent | 5b8099887a4f788aa49072c99eea808f4e1f3dc4 (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/loader.c')
-rw-r--r-- | main/loader.c | 30 |
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; |