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: https://origsvn.digium.com/svn/asterisk/trunk@40949 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Kevin P. Fleming
2006-08-23 19:28:13 +00:00
parent e690d7d34c
commit 7eecf0bfbc
4 changed files with 106 additions and 9 deletions

72
configure vendored
View File

@@ -1,5 +1,5 @@
#! /bin/sh #! /bin/sh
# From configure.ac Revision: 40790 . # From configure.ac Revision: 40837 .
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.60. # Generated by GNU Autoconf 2.60.
# #
@@ -13651,6 +13651,76 @@ echo "${ECHO_T}no" >&6; }
fi fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
{ echo "$as_me:$LINENO: checking checking for RTLD_NOLOAD" >&5
echo $ECHO_N "checking checking for RTLD_NOLOAD... $ECHO_C" >&6; }
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <dlfcn.h>
int
main ()
{
int foo = RTLD_NOLOAD;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
{ (case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_try") 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_try") 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
{ echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
cat >>confdefs.h <<\_ACEOF
#define HAVE_RTLD_NOLOAD 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext \ rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext conftest$ac_exeext conftest.$ac_ext

View File

@@ -237,6 +237,15 @@ AC_LINK_IFELSE(
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
) )
AC_MSG_CHECKING(checking for RTLD_NOLOAD)
AC_LINK_IFELSE(
AC_LANG_PROGRAM([#include <dlfcn.h>],
[int foo = RTLD_NOLOAD;]),
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_RTLD_NOLOAD], 1, [Define to 1 if your system has a dynamic linker that supports RTLD_NOLOAD.]),
AC_MSG_RESULT(no)
)
AST_GCC_ATTRIBUTE(pure) AST_GCC_ATTRIBUTE(pure)
AST_GCC_ATTRIBUTE(malloc) AST_GCC_ATTRIBUTE(malloc)
AST_GCC_ATTRIBUTE(const) AST_GCC_ATTRIBUTE(const)

View File

@@ -270,6 +270,10 @@
/* Define to 1 if you have the `rint' function. */ /* Define to 1 if you have the `rint' function. */
#undef HAVE_RINT #undef HAVE_RINT
/* Define to 1 if your system has a dynamic linker that supports RTLD_NOLOAD.
*/
#undef HAVE_RTLD_NOLOAD
/* Define to 1 if you have the `select' function. */ /* Define to 1 if you have the `select' function. */
#undef HAVE_SELECT #undef HAVE_SELECT

View File

@@ -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) static void unload_dynamic_module(struct ast_module *mod)
{ {
if (mod->lib) if (mod->lib)
dlclose(mod->lib); while (!dlclose(mod->lib));
/* WARNING: the structure pointed to by mod is now gone! */ /* 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))) { if (resource_being_loaded != (mod = AST_LIST_LAST(&module_list))) {
/* no, it did not, so close it and return */ /* 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(), /* note that the module's destructor will call ast_module_unregister(),
which will free the structure we allocated in resource_being_loaded */ which will free the structure we allocated in resource_being_loaded */
return NULL; 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); 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, /* if we are being asked only to load modules that provide global symbols,
and this one does not, then close it and return */ 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; 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 */ /* 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 /* since the module was successfully opened, and it registered itself
the previous time we did that, we're going to assume it worked this the previous time we did that, we're going to assume it worked this
time too :) */ time too :) */
#endif
AST_LIST_LAST(&module_list)->lib = lib; AST_LIST_LAST(&module_list)->lib = lib;
resource_being_loaded = NULL; resource_being_loaded = NULL;