@ -54,7 +54,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
# include "asterisk/features_config.h"
# include "asterisk/features_config.h"
# include "asterisk/dsp.h"
# include "asterisk/dsp.h"
# include "asterisk/udptl.h"
# include "asterisk/udptl.h"
# include "asterisk/ heap .h"
# include "asterisk/ vector .h"
# include "asterisk/app.h"
# include "asterisk/app.h"
# include "asterisk/test.h"
# include "asterisk/test.h"
# include "asterisk/sounds_index.h"
# include "asterisk/sounds_index.h"
@ -112,6 +112,8 @@ static const unsigned char expected_key[] =
static char buildopt_sum [ 33 ] = AST_BUILDOPT_SUM ;
static char buildopt_sum [ 33 ] = AST_BUILDOPT_SUM ;
AST_VECTOR ( module_vector , struct ast_module * ) ;
/*!
/*!
* \ brief Internal flag to indicate all modules have been initially loaded .
* \ brief Internal flag to indicate all modules have been initially loaded .
*/
*/
@ -144,6 +146,23 @@ struct ast_module {
static AST_DLLIST_HEAD_STATIC ( module_list , ast_module ) ;
static AST_DLLIST_HEAD_STATIC ( module_list , ast_module ) ;
static int module_vector_cmp ( struct ast_module * a , struct ast_module * b )
{
/* if load_pri is not set, default is 128. Lower is better */
int a_pri = ast_test_flag ( a - > info , AST_MODFLAG_LOAD_ORDER )
? a - > info - > load_pri : AST_MODPRI_DEFAULT ;
int b_pri = ast_test_flag ( b - > info , AST_MODFLAG_LOAD_ORDER )
? b - > info - > load_pri : AST_MODPRI_DEFAULT ;
/*
* Returns comparison values for a vector sorted by priority .
* < 0 a_pri < b_pri
* = 0 a_pri = = b_pri
* > 0 a_pri > b_pri
*/
return a_pri - b_pri ;
}
const char * ast_module_name ( const struct ast_module * mod )
const char * ast_module_name ( const struct ast_module * mod )
{
{
if ( ! mod | | ! mod - > info ) {
if ( ! mod | | ! mod - > info ) {
@ -522,8 +541,6 @@ static void unload_dynamic_module(struct ast_module *mod)
# endif
# endif
}
}
static enum ast_module_load_result load_resource ( const char * resource_name , unsigned int global_symbols_only , unsigned int suppress_logging , struct ast_heap * resource_heap , int required ) ;
# define MODULE_LOCAL_ONLY (void *)-1
# define MODULE_LOCAL_ONLY (void *)-1
/*!
/*!
@ -572,7 +589,7 @@ static struct ast_module *load_dlopen(const char *resource_in, const char *so_ex
return mod ;
return mod ;
}
}
static struct ast_module * load_dynamic_module ( const char * resource_in , unsigned int global_symbols_only , unsigned int suppress_logging , struct ast_heap * resource_heap )
static struct ast_module * load_dynamic_module ( const char * resource_in , unsigned int global_symbols_only , unsigned int suppress_logging )
{
{
char fn [ PATH_MAX ] ;
char fn [ PATH_MAX ] ;
struct ast_module * mod ;
struct ast_module * mod ;
@ -1141,13 +1158,13 @@ static enum ast_module_load_result start_resource(struct ast_module *mod)
/*! loads a resource based upon resource_name. If global_symbols_only is set
/*! loads a resource based upon resource_name. If global_symbols_only is set
* only modules with global symbols will be loaded .
* only modules with global symbols will be loaded .
*
*
* If the ast_heap is provided ( not NULL ) the module is found and added to the
* If the module_vector is provided ( not NULL ) the module is found and added to the
* heap without running the module ' s load ( ) function . By doing this , modules
* vector without running the module ' s load ( ) function . By doing this , modules
* added to the resource_heap can be initialized later in order by priority .
* can be initialized later in order by priority and dependencies .
*
*
* If the ast_heap is not provided , the module ' s load function will be executed
* If the module_vector is not provided , the module ' s load function will be executed
* immediately */
* immediately */
static enum ast_module_load_result load_resource ( const char * resource_name , unsigned int global_symbols_only , unsigned int suppress_logging , struct ast_heap * resource_heap , int required )
static enum ast_module_load_result load_resource ( const char * resource_name , unsigned int global_symbols_only , unsigned int suppress_logging , struct module_vector * resource_heap , int required )
{
{
struct ast_module * mod ;
struct ast_module * mod ;
enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS ;
enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS ;
@ -1160,7 +1177,7 @@ static enum ast_module_load_result load_resource(const char *resource_name, unsi
if ( global_symbols_only & & ! ast_test_flag ( mod - > info , AST_MODFLAG_GLOBAL_SYMBOLS ) )
if ( global_symbols_only & & ! ast_test_flag ( mod - > info , AST_MODFLAG_GLOBAL_SYMBOLS ) )
return AST_MODULE_LOAD_SKIP ;
return AST_MODULE_LOAD_SKIP ;
} else {
} else {
mod = load_dynamic_module ( resource_name , global_symbols_only , suppress_logging , resource_heap );
mod = load_dynamic_module ( resource_name , global_symbols_only , suppress_logging );
if ( mod = = MODULE_LOCAL_ONLY ) {
if ( mod = = MODULE_LOCAL_ONLY ) {
return AST_MODULE_LOAD_SKIP ;
return AST_MODULE_LOAD_SKIP ;
}
}
@ -1173,21 +1190,26 @@ static enum ast_module_load_result load_resource(const char *resource_name, unsi
}
}
if ( inspect_module ( mod ) ) {
if ( inspect_module ( mod ) ) {
ast_log ( LOG_WARNING , " Module '%s' could not be loaded. \n " , resource_name ) ;
goto prestart_error ;
unload_dynamic_module ( mod ) ;
return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE ;
}
}
mod - > flags . declined = 0 ;
mod - > flags . declined = 0 ;
if ( resource_heap ) {
if ( resource_heap ) {
ast_heap_push ( resource_heap , mod ) ;
if ( AST_VECTOR_ADD_SORTED ( resource_heap , mod , module_vector_cmp ) ) {
goto prestart_error ;
}
res = AST_MODULE_LOAD_PRIORITY ;
res = AST_MODULE_LOAD_PRIORITY ;
} else {
} else {
res = start_resource ( mod ) ;
res = start_resource ( mod ) ;
}
}
return res ;
return res ;
prestart_error :
ast_log ( LOG_WARNING , " Module '%s' could not be loaded. \n " , resource_name ) ;
unload_dynamic_module ( mod ) ;
return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE ;
}
}
int ast_load_resource ( const char * resource_name )
int ast_load_resource ( const char * resource_name )
@ -1235,23 +1257,6 @@ static struct load_order_entry *add_to_load_order(const char *resource, struct l
return order ;
return order ;
}
}
static int mod_load_cmp ( void * a , void * b )
{
struct ast_module * a_mod = ( struct ast_module * ) a ;
struct ast_module * b_mod = ( struct ast_module * ) b ;
/* if load_pri is not set, default is 128. Lower is better */
int a_pri = ast_test_flag ( a_mod - > info , AST_MODFLAG_LOAD_ORDER ) ? a_mod - > info - > load_pri : 128 ;
int b_pri = ast_test_flag ( b_mod - > info , AST_MODFLAG_LOAD_ORDER ) ? b_mod - > info - > load_pri : 128 ;
/*
* Returns comparison values for a min - heap
* < 0 a_pri > b_pri
* = 0 a_pri = = b_pri
* > 0 a_pri < b_pri
*/
return b_pri - a_pri ;
}
AST_LIST_HEAD_NOLOCK ( load_retries , load_order_entry ) ;
AST_LIST_HEAD_NOLOCK ( load_retries , load_order_entry ) ;
/*! loads modules in order by load_pri, updates mod_count
/*! loads modules in order by load_pri, updates mod_count
@ -1259,9 +1264,8 @@ AST_LIST_HEAD_NOLOCK(load_retries, load_order_entry);
*/
*/
static int load_resource_list ( struct load_order * load_order , unsigned int global_symbols , int * mod_count )
static int load_resource_list ( struct load_order * load_order , unsigned int global_symbols , int * mod_count )
{
{
struct ast_heap * resource_heap ;
struct module_vector resource_heap ;
struct load_order_entry * order ;
struct load_order_entry * order ;
struct ast_module * mod ;
struct load_retries load_retries ;
struct load_retries load_retries ;
int count = 0 ;
int count = 0 ;
int res = 0 ;
int res = 0 ;
@ -1270,7 +1274,9 @@ static int load_resource_list(struct load_order *load_order, unsigned int global
AST_LIST_HEAD_INIT_NOLOCK ( & load_retries ) ;
AST_LIST_HEAD_INIT_NOLOCK ( & load_retries ) ;
if ( ! ( resource_heap = ast_heap_create ( 8 , mod_load_cmp , - 1 ) ) ) {
if ( AST_VECTOR_INIT ( & resource_heap , 500 ) ) {
ast_log ( LOG_ERROR , " Failed to initialize module loader. \n " ) ;
return - 1 ;
return - 1 ;
}
}
@ -1279,7 +1285,7 @@ static int load_resource_list(struct load_order *load_order, unsigned int global
enum ast_module_load_result lres ;
enum ast_module_load_result lres ;
/* Suppress log messages unless this is the last pass */
/* Suppress log messages unless this is the last pass */
lres = load_resource ( order - > resource , global_symbols , 1 , resource_heap , order - > required ) ;
lres = load_resource ( order - > resource , global_symbols , 1 , & resource_heap , order - > required ) ;
ast_debug ( 3 , " PASS 0: %-46s %d %d \n " , order - > resource , lres , global_symbols ) ;
ast_debug ( 3 , " PASS 0: %-46s %d %d \n " , order - > resource , lres , global_symbols ) ;
switch ( lres ) {
switch ( lres ) {
case AST_MODULE_LOAD_SUCCESS :
case AST_MODULE_LOAD_SUCCESS :
@ -1303,7 +1309,7 @@ static int load_resource_list(struct load_order *load_order, unsigned int global
*/
*/
break ;
break ;
case AST_MODULE_LOAD_PRIORITY :
case AST_MODULE_LOAD_PRIORITY :
/* load_resource worked and the module was added to the priority heap */
/* load_resource worked and the module was added to the priority vector */
AST_LIST_REMOVE_CURRENT ( entry ) ;
AST_LIST_REMOVE_CURRENT ( entry ) ;
ast_free ( order - > resource ) ;
ast_free ( order - > resource ) ;
ast_free ( order ) ;
ast_free ( order ) ;
@ -1318,7 +1324,7 @@ static int load_resource_list(struct load_order *load_order, unsigned int global
enum ast_module_load_result lres ;
enum ast_module_load_result lres ;
/* Suppress log messages unless this is the last pass */
/* Suppress log messages unless this is the last pass */
lres = load_resource ( order - > resource , global_symbols , ( i < LOAD_RETRIES - 1 ) , resource_heap , order - > required ) ;
lres = load_resource ( order - > resource , global_symbols , ( i < LOAD_RETRIES - 1 ) , & resource_heap , order - > required ) ;
ast_debug ( 3 , " PASS %d %-46s %d %d \n " , i + 1 , order - > resource , lres , global_symbols ) ;
ast_debug ( 3 , " PASS %d %-46s %d %d \n " , i + 1 , order - > resource , lres , global_symbols ) ;
switch ( lres ) {
switch ( lres ) {
/* These are all retryable. */
/* These are all retryable. */
@ -1356,7 +1362,8 @@ static int load_resource_list(struct load_order *load_order, unsigned int global
}
}
/* second remove modules from heap sorted by priority */
/* second remove modules from heap sorted by priority */
while ( ( mod = ast_heap_pop ( resource_heap ) ) ) {
for ( i = 0 ; i < AST_VECTOR_SIZE ( & resource_heap ) ; i + + ) {
struct ast_module * mod = AST_VECTOR_GET ( & resource_heap , i ) ;
enum ast_module_load_result lres ;
enum ast_module_load_result lres ;
lres = start_resource ( mod ) ;
lres = start_resource ( mod ) ;
@ -1386,7 +1393,7 @@ done:
if ( mod_count ) {
if ( mod_count ) {
* mod_count + = count ;
* mod_count + = count ;
}
}
ast_heap_destroy( resource_heap ) ;
AST_VECTOR_FREE( & resource_heap ) ;
return res ;
return res ;
}
}