mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-14 16:15:04 +00:00
add our own module load code (LBAPR-1)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@10272 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
837b2c9bed
commit
b17ebda4df
@ -70,6 +70,7 @@ src/switch_core_port_allocator.c \
|
|||||||
src/switch_core.c \
|
src/switch_core.c \
|
||||||
src/switch_scheduler.c \
|
src/switch_scheduler.c \
|
||||||
src/switch_core_db.c\
|
src/switch_core_db.c\
|
||||||
|
src/switch_dso.c\
|
||||||
src/switch_loadable_module.c \
|
src/switch_loadable_module.c \
|
||||||
src/switch_utils.c \
|
src/switch_utils.c \
|
||||||
src/switch_event.c \
|
src/switch_event.c \
|
||||||
@ -114,6 +115,7 @@ src/include/switch_config.h\
|
|||||||
src/include/switch_event.h\
|
src/include/switch_event.h\
|
||||||
src/include/switch_frame.h\
|
src/include/switch_frame.h\
|
||||||
src/include/switch_ivr.h\
|
src/include/switch_ivr.h\
|
||||||
|
src/include/switch_dso.h\
|
||||||
src/include/switch_loadable_module.h\
|
src/include/switch_loadable_module.h\
|
||||||
src/include/switch_module_interfaces.h\
|
src/include/switch_module_interfaces.h\
|
||||||
src/include/switch_platform.h\
|
src/include/switch_platform.h\
|
||||||
|
@ -98,6 +98,7 @@
|
|||||||
#include "switch_apr.h"
|
#include "switch_apr.h"
|
||||||
|
|
||||||
#include "switch_core_db.h"
|
#include "switch_core_db.h"
|
||||||
|
#include "switch_dso.h"
|
||||||
#include "switch_regex.h"
|
#include "switch_regex.h"
|
||||||
#include "switch_core.h"
|
#include "switch_core.h"
|
||||||
#include "switch_loadable_module.h"
|
#include "switch_loadable_module.h"
|
||||||
|
@ -21,21 +21,19 @@
|
|||||||
#ifndef _SWITCH_DSO_H
|
#ifndef _SWITCH_DSO_H
|
||||||
#define _SWITCH_DSO_H
|
#define _SWITCH_DSO_H
|
||||||
|
|
||||||
typedef void (*switch_func_ptr_t) (void);
|
typedef int (*switch_dso_func_t) (void);
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
typedef HINSTANCE switch_dso_lib_t;
|
typedef HINSTANCE switch_dso_lib_t;
|
||||||
#else
|
#else
|
||||||
typedef void * switch_dso_lib_t;
|
typedef void * switch_dso_lib_t;
|
||||||
#endif
|
#endif
|
||||||
#ifdef WIN32
|
|
||||||
typedef FARPROC switch_dso_func_t;
|
typedef void * switch_dso_data_t;
|
||||||
#else
|
|
||||||
typedef void * switch_dso_func_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void switch_dso_destroy(switch_dso_lib_t *lib);
|
void switch_dso_destroy(switch_dso_lib_t *lib);
|
||||||
switch_dso_lib_t switch_dso_open(const char *path, int global, char **err);
|
switch_dso_lib_t switch_dso_open(const char *path, int global, char **err);
|
||||||
switch_dso_func_t switch_dso_func_sym(switch_dso_lib_t lib, const char *sym, char **err);
|
switch_dso_func_t switch_dso_func_sym(switch_dso_lib_t lib, const char *sym, char **err);
|
||||||
|
void *switch_dso_data_sym(switch_dso_lib_t lib, const char *sym, char **err);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -54,9 +54,19 @@ switch_dso_func_t switch_dso_func_sym(switch_dso_lib_t lib, const char *sym, cha
|
|||||||
DWORD error = GetLastError();
|
DWORD error = GetLastError();
|
||||||
*err = switch_mprintf("dll sym error [%ul]\n", error);
|
*err = switch_mprintf("dll sym error [%ul]\n", error);
|
||||||
}
|
}
|
||||||
return func;
|
return (switch_dso_func_t)func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *switch_dso_data_sym(switch_dso_lib_t lib, const char *sym, char **err) {
|
||||||
|
FARPROC addr = GetProcAddress(lib, sym);
|
||||||
|
if (!addr) {
|
||||||
|
DWORD error = GetLastError();
|
||||||
|
*err = switch_mprintf("dll sym error [%ul]\n", error);
|
||||||
|
}
|
||||||
|
return (void *)(intptr_t)addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
** {========================================================================
|
** {========================================================================
|
||||||
@ -92,13 +102,22 @@ switch_dso_lib_t switch_dso_open(const char *path, int global, char **err) {
|
|||||||
return lib;
|
return lib;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *switch_dso_func_sym(switch_dso_lib_t lib, const char *sym, char **err) {
|
switch_dso_func_t switch_dso_func_sym(switch_dso_lib_t lib, const char *sym, char **err) {
|
||||||
void *func = dlsym(lib, sym);
|
void *func = dlsym(lib, sym);
|
||||||
if (!func) {
|
if (!func) {
|
||||||
*err = strdup(dlerror());
|
*err = strdup(dlerror());
|
||||||
}
|
}
|
||||||
return func;
|
return (switch_dso_func_t)(intptr_t)func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *switch_dso_data_sym(switch_dso_lib_t lib, const char *sym, char **err) {
|
||||||
|
void *addr = dlsym(lib, sym);
|
||||||
|
if (!addr) {
|
||||||
|
*err = strdup(dlerror());
|
||||||
|
}
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/* }====================================================== */
|
/* }====================================================== */
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ struct switch_loadable_module {
|
|||||||
char *filename;
|
char *filename;
|
||||||
int perm;
|
int perm;
|
||||||
switch_loadable_module_interface_t *module_interface;
|
switch_loadable_module_interface_t *module_interface;
|
||||||
void *lib;
|
switch_dso_lib_t lib;
|
||||||
switch_module_load_t switch_module_load;
|
switch_module_load_t switch_module_load;
|
||||||
switch_module_runtime_t switch_module_runtime;
|
switch_module_runtime_t switch_module_runtime;
|
||||||
switch_module_shutdown_t switch_module_shutdown;
|
switch_module_shutdown_t switch_module_shutdown;
|
||||||
@ -75,6 +75,7 @@ struct switch_loadable_module_container {
|
|||||||
|
|
||||||
static struct switch_loadable_module_container loadable_modules;
|
static struct switch_loadable_module_container loadable_modules;
|
||||||
static void do_shutdown(switch_loadable_module_t *module, switch_bool_t shutdown, switch_bool_t unload);
|
static void do_shutdown(switch_loadable_module_t *module, switch_bool_t shutdown, switch_bool_t unload);
|
||||||
|
static switch_status_t switch_loadable_module_load_module_ex(char *dir, char *fname, switch_bool_t runtime, switch_bool_t global, const char **err);
|
||||||
|
|
||||||
static void *switch_loadable_module_exec(switch_thread_t *thread, void *obj)
|
static void *switch_loadable_module_exec(switch_thread_t *thread, void *obj)
|
||||||
{
|
{
|
||||||
@ -676,22 +677,19 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static switch_status_t switch_loadable_module_load_file(char *path, char *filename, switch_loadable_module_t **new_module)
|
static switch_status_t switch_loadable_module_load_file(char *path, char *filename, switch_bool_t global, switch_loadable_module_t **new_module)
|
||||||
{
|
{
|
||||||
switch_loadable_module_t *module = NULL;
|
switch_loadable_module_t *module = NULL;
|
||||||
switch_dso_handle_t *dso = NULL;
|
switch_dso_lib_t dso = NULL;
|
||||||
apr_status_t status = SWITCH_STATUS_SUCCESS;
|
apr_status_t status = SWITCH_STATUS_SUCCESS;
|
||||||
switch_dso_handle_sym_t interface_struct_handle = NULL;
|
switch_loadable_module_function_table_t *interface_struct_handle = NULL;
|
||||||
switch_loadable_module_function_table_t *mod_interface_functions = NULL;
|
switch_loadable_module_function_table_t *mod_interface_functions = NULL;
|
||||||
char *struct_name = 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;
|
|
||||||
switch_module_load_t load_func_ptr = NULL;
|
switch_module_load_t load_func_ptr = NULL;
|
||||||
int loading = 1;
|
int loading = 1;
|
||||||
const char *err = NULL;
|
|
||||||
switch_loadable_module_interface_t *module_interface = NULL;
|
switch_loadable_module_interface_t *module_interface = NULL;
|
||||||
char derr[512] = "";
|
char *derr = NULL;
|
||||||
|
const char *err = NULL;
|
||||||
switch_memory_pool_t *pool;
|
switch_memory_pool_t *pool;
|
||||||
|
|
||||||
switch_assert(path != NULL);
|
switch_assert(path != NULL);
|
||||||
@ -702,36 +700,40 @@ static switch_status_t switch_loadable_module_load_file(char *path, char *filena
|
|||||||
struct_name = switch_core_sprintf(pool, "%s_module_interface", filename);
|
struct_name = switch_core_sprintf(pool, "%s_module_interface", filename);
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
status = switch_dso_load(&dso, "FreeSwitch.dll", loadable_modules.pool);
|
dso = switch_dso_open("FreeSwitch.dll", global, &derr);
|
||||||
#elif defined (MACOSX) || defined(DARWIN)
|
#elif defined (MACOSX) || defined(DARWIN)
|
||||||
status = switch_dso_load(&dso, SWITCH_PREFIX_DIR "/lib/libfreeswitch.dylib", loadable_modules.pool);
|
dso = switch_dso_open(SWITCH_PREFIX_DIR "/lib/libfreeswitch.dylib", global, &derr);
|
||||||
#else
|
#else
|
||||||
status = switch_dso_load(&dso, NULL, loadable_modules.pool);
|
dso = switch_dso_open(NULL, global, &derr);
|
||||||
#endif
|
#endif
|
||||||
status = switch_dso_sym(&interface_struct_handle, dso, struct_name);
|
if (!derr && dso) {
|
||||||
|
interface_struct_handle = switch_dso_data_sym(dso, struct_name, &derr);
|
||||||
if (!interface_struct_handle) {
|
|
||||||
status = switch_dso_load(&dso, path, loadable_modules.pool);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_safe_free(derr)
|
||||||
|
|
||||||
|
if (!interface_struct_handle) {
|
||||||
|
dso = switch_dso_open(path, global, &derr);
|
||||||
|
}
|
||||||
|
|
||||||
while (loading) {
|
while (loading) {
|
||||||
if (status != APR_SUCCESS) {
|
if (derr) {
|
||||||
switch_dso_error(dso, derr, sizeof(derr));
|
|
||||||
err = derr;
|
err = derr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!interface_struct_handle) {
|
if (!interface_struct_handle) {
|
||||||
status = switch_dso_sym(&interface_struct_handle, dso, struct_name);
|
interface_struct_handle = switch_dso_data_sym(dso, struct_name, &derr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (derr) {
|
||||||
|
err = derr;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interface_struct_handle) {
|
if (interface_struct_handle) {
|
||||||
mod_interface_functions = interface_struct_handle;
|
mod_interface_functions = interface_struct_handle;
|
||||||
load_func_ptr = mod_interface_functions->load;
|
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) {
|
if (load_func_ptr == NULL) {
|
||||||
@ -765,6 +767,7 @@ static switch_status_t switch_loadable_module_load_file(char *path, char *filena
|
|||||||
switch_core_destroy_memory_pool(&pool);
|
switch_core_destroy_memory_pool(&pool);
|
||||||
}
|
}
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Loading module %s\n**%s**\n", path, err);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Loading module %s\n**%s**\n", path, err);
|
||||||
|
switch_safe_free(derr);
|
||||||
return SWITCH_STATUS_GENERR;
|
return SWITCH_STATUS_GENERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -776,11 +779,6 @@ static switch_status_t switch_loadable_module_load_file(char *path, char *filena
|
|||||||
if (mod_interface_functions) {
|
if (mod_interface_functions) {
|
||||||
module->switch_module_shutdown = mod_interface_functions->shutdown;
|
module->switch_module_shutdown = mod_interface_functions->shutdown;
|
||||||
module->switch_module_runtime = mod_interface_functions->runtime;
|
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;
|
module->lib = dso;
|
||||||
@ -791,8 +789,12 @@ static switch_status_t switch_loadable_module_load_file(char *path, char *filena
|
|||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_loadable_module_load_module(char *dir, char *fname, switch_bool_t runtime, const char **err)
|
SWITCH_DECLARE(switch_status_t) switch_loadable_module_load_module(char *dir, char *fname, switch_bool_t runtime, const char **err)
|
||||||
|
{
|
||||||
|
return switch_loadable_module_load_module_ex(dir, fname, runtime, SWITCH_FALSE, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
static switch_status_t switch_loadable_module_load_module_ex(char *dir, char *fname, switch_bool_t runtime, switch_bool_t global, const char **err)
|
||||||
{
|
{
|
||||||
switch_size_t len = 0;
|
switch_size_t len = 0;
|
||||||
char *path;
|
char *path;
|
||||||
@ -833,7 +835,7 @@ 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);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Module %s Already Loaded!\n", file);
|
||||||
*err = "Module already loaded";
|
*err = "Module already loaded";
|
||||||
status = SWITCH_STATUS_FALSE;
|
status = SWITCH_STATUS_FALSE;
|
||||||
} else if ((status = switch_loadable_module_load_file(path, file, &new_module)) == SWITCH_STATUS_SUCCESS) {
|
} else if ((status = switch_loadable_module_load_file(path, file, global, &new_module)) == SWITCH_STATUS_SUCCESS) {
|
||||||
if ((status = switch_loadable_module_process(file, new_module)) == SWITCH_STATUS_SUCCESS && runtime) {
|
if ((status = switch_loadable_module_process(file, new_module)) == SWITCH_STATUS_SUCCESS && runtime) {
|
||||||
if (new_module->switch_module_runtime) {
|
if (new_module->switch_module_runtime) {
|
||||||
switch_core_launch_thread(switch_loadable_module_exec, new_module, new_module->pool);
|
switch_core_launch_thread(switch_loadable_module_exec, new_module, new_module->pool);
|
||||||
@ -1042,12 +1044,15 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init()
|
|||||||
switch_xml_t mods, ld;
|
switch_xml_t mods, ld;
|
||||||
if ((mods = switch_xml_child(cfg, "modules"))) {
|
if ((mods = switch_xml_child(cfg, "modules"))) {
|
||||||
for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) {
|
for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) {
|
||||||
|
switch_bool_t global = SWITCH_FALSE;
|
||||||
const char *val = switch_xml_attr_soft(ld, "module");
|
const char *val = switch_xml_attr_soft(ld, "module");
|
||||||
|
const char *sglobal = switch_xml_attr_soft(ld, "global");
|
||||||
if (switch_strlen_zero(val) || (strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT))) {
|
if (switch_strlen_zero(val) || (strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT))) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) val, SWITCH_FALSE, &err);
|
global = switch_true(sglobal);
|
||||||
|
switch_loadable_module_load_module_ex((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) val, SWITCH_FALSE, global, &err);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1062,12 +1067,15 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init()
|
|||||||
|
|
||||||
if ((mods = switch_xml_child(cfg, "modules"))) {
|
if ((mods = switch_xml_child(cfg, "modules"))) {
|
||||||
for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) {
|
for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) {
|
||||||
|
switch_bool_t global = SWITCH_FALSE;
|
||||||
const char *val = switch_xml_attr_soft(ld, "module");
|
const char *val = switch_xml_attr_soft(ld, "module");
|
||||||
|
const char *sglobal = switch_xml_attr_soft(ld, "global");
|
||||||
if (switch_strlen_zero(val) || (strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT))) {
|
if (switch_strlen_zero(val) || (strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT))) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) val, SWITCH_FALSE, &err);
|
global = switch_true(sglobal);
|
||||||
|
switch_loadable_module_load_module_ex((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) val, SWITCH_FALSE, global, &err);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1135,8 +1143,7 @@ static void do_shutdown(switch_loadable_module_t *module, switch_bool_t shutdown
|
|||||||
if (unload && module->status != SWITCH_STATUS_NOUNLOAD && !(flags & SCF_VG)) {
|
if (unload && module->status != SWITCH_STATUS_NOUNLOAD && !(flags & SCF_VG)) {
|
||||||
switch_memory_pool_t *pool;
|
switch_memory_pool_t *pool;
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s unloaded.\n", module->module_interface->module_name);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s unloaded.\n", module->module_interface->module_name);
|
||||||
switch_dso_unload(module->lib);
|
switch_dso_destroy(&module->lib);
|
||||||
module->lib = NULL;
|
|
||||||
if ((pool = module->pool)) {
|
if ((pool = module->pool)) {
|
||||||
module = NULL;
|
module = NULL;
|
||||||
switch_core_destroy_memory_pool(&pool);
|
switch_core_destroy_memory_pool(&pool);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user