From 14608093b12ae39b331509b5e07b539fb8dd8183 Mon Sep 17 00:00:00 2001 From: Michael Jerris <mike@jerris.com> Date: Wed, 13 Jun 2007 14:35:55 +0000 Subject: [PATCH] add new macros and approach to module loader. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5337 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_platform.h | 4 + src/include/switch_types.h | 36 +++++++-- src/mod/endpoints/mod_iax/mod_iax.c | 14 ++-- src/mod/endpoints/mod_sofia/mod_sofia.c | 8 +- src/mod/endpoints/mod_sofia/mod_sofia.h | 2 +- src/mod/endpoints/mod_sofia/sofia.c | 2 +- src/switch_loadable_module.c | 97 ++++++++++--------------- 7 files changed, 89 insertions(+), 74 deletions(-) diff --git a/src/include/switch_platform.h b/src/include/switch_platform.h index 9585dc34b4..798f562a65 100644 --- a/src/include/switch_platform.h +++ b/src/include/switch_platform.h @@ -146,10 +146,13 @@ typedef int gid_t; #endif #if defined(SWITCH_MOD_DECLARE_STATIC) #define SWITCH_MOD_DECLARE(type) type __cdecl +#define SWITCH_MOD_DECLARE_DATA #elif defined(MOD_EXPORTS) #define SWITCH_MOD_DECLARE(type) __declspec(dllexport) type __cdecl +#define SWITCH_MOD_DECLARE_DATA __declspec(dllexport) #else #define SWITCH_MOD_DECLARE(type) __declspec(dllimport) type __cdecl +#define SWITCH_MOD_DECLARE_DATA __declspec(dllimport) #endif #define SIGHUP SIGTERM #ifndef S_IRUSR @@ -164,6 +167,7 @@ typedef int gid_t; #define SWITCH_DECLARE_NONSTD(type) type #define SWITCH_MOD_DECLARE(type) type #define SWITCH_DECLARE_DATA +#define SWITCH_MOD_DECLARE_DATA #define SWITCH_THREAD_FUNC #endif #ifdef DOXYGEN diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 33013e31b8..51608465ef 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1045,19 +1045,41 @@ typedef struct { } switch_input_args_t; typedef switch_status_t (*switch_say_callback_t) (switch_core_session_t *session, char *tosay, switch_say_type_t type, switch_say_method_t method, switch_input_args_t *args); -typedef switch_status_t (*switch_module_load_t) (switch_loadable_module_interface_t **, char *); -typedef switch_status_t (*switch_module_reload_t) (void); -typedef switch_status_t (*switch_module_pause_t) (void); -typedef switch_status_t (*switch_module_resume_t) (void); -typedef switch_status_t (*switch_module_status_t) (void); -typedef switch_status_t (*switch_module_runtime_t) (void); -typedef switch_status_t (*switch_module_shutdown_t) (void); typedef struct switch_xml *switch_xml_t; typedef struct switch_core_time_duration switch_core_time_duration_t; typedef switch_xml_t(*switch_xml_search_function_t) (const char *section, const char *tag_name, const char *key_name, const char *key_value, const char *params, void *user_data); + +#define SWITCH_API_VERSION 1 +#define SWITCH_MODULE_LOAD_ARGS (const switch_loadable_module_interface_t **module_interface, char *filename) +#define SWITCH_MODULE_RUNTIME_ARGS (void) +#define SWITCH_MODULE_SHUTDOWN_ARGS (void) +typedef switch_status_t (*switch_module_load_t) SWITCH_MODULE_LOAD_ARGS ; +typedef switch_status_t (*switch_module_runtime_t) SWITCH_MODULE_RUNTIME_ARGS ; +typedef switch_status_t (*switch_module_shutdown_t) SWITCH_MODULE_SHUTDOWN_ARGS ; +#define SWITCH_MODULE_LOAD_FUNCTION(name) switch_status_t name SWITCH_MODULE_LOAD_ARGS +#define SWITCH_MODULE_RUNTIME_FUNCTION(name) switch_status_t name SWITCH_MODULE_RUNTIME_ARGS +#define SWITCH_MODULE_SHUTDOWN_FUNCTION(name) switch_status_t name SWITCH_MODULE_SHUTDOWN_ARGS + +typedef struct switch_loadable_module_function_table { + int switch_api_version; + switch_module_load_t load; + switch_module_shutdown_t shutdown; + switch_module_runtime_t runtime; +} switch_loadable_module_function_table_t; + +#define SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime) \ +static const char modname[] = #name ; \ +SWITCH_MOD_DECLARE_DATA switch_loadable_module_function_table_t name##_module_interface = { \ + SWITCH_API_VERSION, \ + load, \ + shutdown, \ + runtime \ +} + + /* things we don't deserve to know about */ /*! \brief A channel */ struct switch_channel; diff --git a/src/mod/endpoints/mod_iax/mod_iax.c b/src/mod/endpoints/mod_iax/mod_iax.c index 3f93afe4ce..567e64398c 100644 --- a/src/mod/endpoints/mod_iax/mod_iax.c +++ b/src/mod/endpoints/mod_iax/mod_iax.c @@ -31,6 +31,11 @@ */ #include <switch.h> +SWITCH_MODULE_LOAD_FUNCTION(mod_iax_load); +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_iax_shutdown); +SWITCH_MODULE_RUNTIME_FUNCTION(mod_iax_runtime); +SWITCH_MODULE_DEFINITION(mod_iax, mod_iax_load, mod_iax_shutdown, mod_iax_runtime); + #include <iax2.h> #include <iax-client.h> #include <iax2-parser.h> @@ -38,8 +43,6 @@ #include <sys/timeb.h> #endif -static const char modname[] = "mod_iax"; - static switch_memory_pool_t *module_pool = NULL; static int running = 1; @@ -874,8 +877,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; } - -SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename) +SWITCH_MODULE_LOAD_FUNCTION(mod_iax_load) { if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) { @@ -967,7 +969,7 @@ static switch_status_t tech_media(private_t * tech_pvt, struct iax_event *iaxeve return status; } -SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void) +SWITCH_MODULE_RUNTIME_FUNCTION(mod_iax_runtime) { //int refresh; struct iax_event *iaxevent = NULL; @@ -1217,7 +1219,7 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void) } -SWITCH_MOD_DECLARE(switch_status_t) switch_module_shutdown(void) +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_iax_shutdown) { int x = 0; diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 5c6cbd6417..a61cb17343 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -38,6 +38,10 @@ #include "mod_sofia.h" +SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load); +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown); +SWITCH_MODULE_DEFINITION(mod_sofia, mod_sofia_load, mod_sofia_shutdown, NULL); + struct mod_sofia_globals mod_sofia_globals; const switch_endpoint_interface_t sofia_endpoint_interface; static switch_frame_t silence_frame = { 0 }; @@ -1497,7 +1501,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session return cause; } -SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename) +SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) { silence_frame.data = silence_data; @@ -1575,7 +1579,7 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod } -SWITCH_MOD_DECLARE(switch_status_t) switch_module_shutdown(void) +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown) { int sanity = 0; diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index a9bad614ff..bbb057de64 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -45,7 +45,7 @@ #include <switch_odbc.h> #endif -static const char modname[] = "mod_sofia"; +#define MODNAME "mod_sofia" static const switch_state_handler_table_t noop_state_handler = { 0 }; struct sofia_gateway; typedef struct sofia_gateway sofia_gateway_t; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index f9e7cd6204..6df51c9701 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1931,7 +1931,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session), from_user, profile->dialplan, - displayname, from_user, network_ip, NULL, NULL, NULL, modname, context, destination_number); + displayname, from_user, network_ip, NULL, NULL, NULL, MODNAME, context, destination_number); if (tech_pvt->caller_profile) { diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index a95da577b2..267ab7083b 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -636,11 +636,13 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t } -static switch_status_t switch_loadable_module_load_file(char *filename, switch_loadable_module_t **new_module) +static switch_status_t switch_loadable_module_load_file(char *path, char *filename, switch_loadable_module_t **new_module) { switch_loadable_module_t *module = NULL; switch_dso_handle_t *dso = NULL; apr_status_t status = SWITCH_STATUS_SUCCESS; + switch_loadable_module_function_table_t *mod_interface_functions = NULL; + char *struct_name = NULL; switch_dso_handle_sym_t load_function_handle = NULL; switch_dso_handle_sym_t shutdown_function_handle = NULL; switch_dso_handle_sym_t runtime_function_handle = NULL; @@ -651,10 +653,10 @@ static switch_status_t switch_loadable_module_load_file(char *filename, switch_l char derr[512] = ""; switch_memory_pool_t *pool; - assert(filename != NULL); + assert(path != NULL); *new_module = NULL; - status = switch_dso_load(&dso, filename, loadable_modules.pool); + status = switch_dso_load(&dso, path, loadable_modules.pool); if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n"); @@ -668,8 +670,14 @@ static switch_status_t switch_loadable_module_load_file(char *filename, switch_l break; } - status = switch_dso_sym(&load_function_handle, dso, "switch_module_load"); - load_func_ptr = (switch_module_load_t) (intptr_t) load_function_handle; + struct_name = switch_core_sprintf(pool, "%s_module_interface", filename); + status = switch_dso_sym(&mod_interface_functions, dso, struct_name); + if (mod_interface_functions) { + load_func_ptr = mod_interface_functions->load; + } else { + status = switch_dso_sym(&load_function_handle, dso, "switch_module_load"); + load_func_ptr = (switch_module_load_t) (intptr_t) load_function_handle; + } if (load_func_ptr == NULL) { err = "Cannot locate symbol 'switch_module_load' please make sure this is a vaild module."; @@ -701,19 +709,24 @@ static switch_status_t switch_loadable_module_load_file(char *filename, switch_l if (pool) { switch_core_destroy_memory_pool(&pool); } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Loading module %s\n**%s**\n", filename, err); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Loading module %s\n**%s**\n", path, err); return SWITCH_STATUS_GENERR; } module->pool = pool; - module->filename = switch_core_strdup(module->pool, filename); + module->filename = switch_core_strdup(module->pool, path); module->module_interface = module_interface; module->switch_module_load = load_func_ptr; - switch_dso_sym(&shutdown_function_handle, dso, "switch_module_shutdown"); - module->switch_module_shutdown = (switch_module_shutdown_t) (intptr_t) shutdown_function_handle; - switch_dso_sym(&runtime_function_handle, dso, "switch_module_runtime"); - module->switch_module_runtime = (switch_module_runtime_t) (intptr_t) runtime_function_handle; + if (mod_interface_functions) { + module->switch_module_shutdown = mod_interface_functions->shutdown; + module->switch_module_runtime = mod_interface_functions->runtime; + } else { + switch_dso_sym(&shutdown_function_handle, dso, "switch_module_shutdown"); + module->switch_module_shutdown = (switch_module_shutdown_t) (intptr_t) shutdown_function_handle; + switch_dso_sym(&runtime_function_handle, dso, "switch_module_runtime"); + module->switch_module_runtime = (switch_module_runtime_t) (intptr_t) runtime_function_handle; + } module->lib = dso; @@ -728,7 +741,7 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_load_module(char *dir, ch { switch_size_t len = 0; char *path; - char *file; + char *file, *dot; switch_loadable_module_t *new_module = NULL; switch_status_t status; @@ -747,20 +760,19 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_load_module(char *dir, ch if (*file == '/') { path = switch_core_strdup(loadable_modules.pool, file); - } else { - if (strchr(file, '.')) { - len = strlen(dir); - len += strlen(file); - len += 4; - path = (char *) switch_core_alloc(loadable_modules.pool, len); - snprintf(path, len, "%s%s%s", dir, SWITCH_PATH_SEPARATOR, file); - } else { - len = strlen(dir); - len += strlen(file); - len += 8; - path = (char *) switch_core_alloc(loadable_modules.pool, len); - snprintf(path, len, "%s%s%s%s", dir, SWITCH_PATH_SEPARATOR, file, ext); + file = (char *)switch_cut_path(file); + if ((dot = strchr(file, '.'))) { + dot = '\0'; } + } else { + if ((dot = strchr(file, '.'))) { + dot = '\0'; + } + len = strlen(dir); + len += strlen(file); + len += 8; + path = (char *) switch_core_alloc(loadable_modules.pool, len); + snprintf(path, len, "%s%s%s%s", dir, SWITCH_PATH_SEPARATOR, file, ext); } switch_mutex_lock(loadable_modules.mutex); @@ -768,8 +780,8 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_load_module(char *dir, ch switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Module %s Already Loaded!\n", file); *err = "Module already loadedn\n"; status = SWITCH_STATUS_FALSE; - } else if ((status = switch_loadable_module_load_file(path, &new_module) == SWITCH_STATUS_SUCCESS)) { - if ((status = switch_loadable_module_process((char *) file, new_module)) == SWITCH_STATUS_SUCCESS && runtime) { + } else if ((status = switch_loadable_module_load_file(path, file, &new_module) == SWITCH_STATUS_SUCCESS)) { + if ((status = switch_loadable_module_process(file, new_module)) == SWITCH_STATUS_SUCCESS && runtime) { if (new_module->switch_module_runtime) { switch_core_launch_thread(switch_loadable_module_exec, new_module, new_module->pool); } @@ -785,37 +797,11 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_load_module(char *dir, ch SWITCH_DECLARE(switch_status_t) switch_loadable_module_unload_module(char *dir, char *fname, const char **err) { - char *path = NULL; - char *file = NULL; switch_loadable_module_t *module = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; -#ifdef WIN32 - const char *ext = ".dll"; -#elif defined (MACOSX) || defined (DARWIN) - const char *ext = ".dylib"; -#else - const char *ext = ".so"; -#endif - - - if (!(file = strdup(fname))) { - abort(); - } - - if (*file == '/') { - path = strdup(file); - } else { - if (strchr(file, '.')) { - path = switch_mprintf("%s%s%s", dir, SWITCH_PATH_SEPARATOR, file); - } else { - path = switch_mprintf("%s%s%s%s", dir, SWITCH_PATH_SEPARATOR, file, ext); - } - } - - switch_mutex_lock(loadable_modules.mutex); - if ((module = switch_core_hash_find(loadable_modules.module_hash, file))) { + if ((module = switch_core_hash_find(loadable_modules.module_hash, fname))) { if (module->perm) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Module is not unloadable.\n"); *err = "Module is not unloadable"; @@ -829,9 +815,6 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_unload_module(char *dir, } switch_mutex_unlock(loadable_modules.mutex); - switch_safe_free(file); - switch_safe_free(path); - return status; }