general improvements
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5078 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
9d5d251987
commit
1be5b1ff45
|
@ -818,6 +818,17 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_destroy(switch_hash_t * hash);
|
||||||
*/
|
*/
|
||||||
SWITCH_DECLARE(switch_status_t) switch_core_hash_insert(switch_hash_t * hash, const char *key, const void *data);
|
SWITCH_DECLARE(switch_status_t) switch_core_hash_insert(switch_hash_t * hash, const char *key, const void *data);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Insert data into a hash
|
||||||
|
\param hash the hash to add data to
|
||||||
|
\param key the name of the key to add the data to
|
||||||
|
\param data the data to add
|
||||||
|
\param mutex optional mutex to lock
|
||||||
|
\return SWITCH_STATUS_SUCCESS if the data is added
|
||||||
|
\note the string key must be a constant or a dynamic string
|
||||||
|
*/
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_core_hash_insert_locked(switch_hash_t * hash, const char *key, const void *data, switch_mutex_t *mutex);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Insert data into a hash with dynamicly allocated key name
|
\brief Insert data into a hash with dynamicly allocated key name
|
||||||
\param hash the hash to add data to
|
\param hash the hash to add data to
|
||||||
|
@ -827,6 +838,16 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_insert(switch_hash_t * hash, co
|
||||||
*/
|
*/
|
||||||
SWITCH_DECLARE(switch_status_t) switch_core_hash_insert_dup(switch_hash_t * hash, const char *key, const void *data);
|
SWITCH_DECLARE(switch_status_t) switch_core_hash_insert_dup(switch_hash_t * hash, const char *key, const void *data);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Insert data into a hash with dynamicly allocated key name
|
||||||
|
\param hash the hash to add data to
|
||||||
|
\param key the name of the key to add the data to
|
||||||
|
\param data the data to add
|
||||||
|
\param mutex optional mutex to lock
|
||||||
|
\return SWITCH_STATUS_SUCCESS if the data is added
|
||||||
|
*/
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_core_hash_insert_dup_locked(switch_hash_t * hash, const char *key, const void *data, switch_mutex_t *mutex);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Delete data from a hash based on desired key
|
\brief Delete data from a hash based on desired key
|
||||||
\param hash the hash to delete from
|
\param hash the hash to delete from
|
||||||
|
@ -835,6 +856,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_insert_dup(switch_hash_t * hash
|
||||||
*/
|
*/
|
||||||
SWITCH_DECLARE(switch_status_t) switch_core_hash_delete(switch_hash_t * hash, const char *key);
|
SWITCH_DECLARE(switch_status_t) switch_core_hash_delete(switch_hash_t * hash, const char *key);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Delete data from a hash based on desired key
|
||||||
|
\param hash the hash to delete from
|
||||||
|
\param key the key from which to delete the data
|
||||||
|
\param mutex optional mutex to lock
|
||||||
|
\return SWITCH_STATUS_SUCCESS if the data is deleted
|
||||||
|
*/
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_locked(switch_hash_t * hash, const char *key, switch_mutex_t *mutex);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Retrieve data from a given hash
|
\brief Retrieve data from a given hash
|
||||||
\param hash the hash to retrieve from
|
\param hash the hash to retrieve from
|
||||||
|
@ -842,6 +872,17 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_delete(switch_hash_t * hash, co
|
||||||
\return a pointer to the data held in the key
|
\return a pointer to the data held in the key
|
||||||
*/
|
*/
|
||||||
SWITCH_DECLARE(void *) switch_core_hash_find(switch_hash_t * hash, const char *key);
|
SWITCH_DECLARE(void *) switch_core_hash_find(switch_hash_t * hash, const char *key);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Retrieve data from a given hash
|
||||||
|
\param hash the hash to retrieve from
|
||||||
|
\param key the key to retrieve
|
||||||
|
\param mutex optional mutex to lock
|
||||||
|
\return a pointer to the data held in the key
|
||||||
|
*/
|
||||||
|
SWITCH_DECLARE(void *) switch_core_hash_find_locked(switch_hash_t * hash, const char *key, switch_mutex_t *mutex);
|
||||||
|
|
||||||
///\}
|
///\}
|
||||||
|
|
||||||
///\defgroup timer Timer Functions
|
///\defgroup timer Timer Functions
|
||||||
|
|
|
@ -228,15 +228,24 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_
|
||||||
*/
|
*/
|
||||||
SWITCH_DECLARE(switch_status_t) switch_api_execute(char *cmd, char *arg, switch_core_session_t *session, switch_stream_handle_t *stream);
|
SWITCH_DECLARE(switch_status_t) switch_api_execute(char *cmd, char *arg, switch_core_session_t *session, switch_stream_handle_t *stream);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Load a module
|
\brief Load a module
|
||||||
\param dir the directory where the module resides
|
\param dir the directory where the module resides
|
||||||
\param fname the file name of the module
|
\param fname the file name of the module
|
||||||
|
\param runtime option to start the runtime thread if it exists
|
||||||
|
\param err pointer to error message
|
||||||
\return the status
|
\return the status
|
||||||
*/
|
*/
|
||||||
SWITCH_DECLARE(switch_status_t) switch_loadable_module_load_module(char *dir, char *fname, switch_bool_t runtime);
|
SWITCH_DECLARE(switch_status_t) switch_loadable_module_load_module(char *dir, char *fname, switch_bool_t runtime, const char **err);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Unoad a module
|
||||||
|
\param dir the directory where the module resides
|
||||||
|
\param fname the file name of the module
|
||||||
|
\param err pointer to error message
|
||||||
|
\return the status
|
||||||
|
*/
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_loadable_module_unload_module(char *dir, char *fname, const char **err);
|
||||||
|
|
||||||
/* Prototypes of module interface functions */
|
/* Prototypes of module interface functions */
|
||||||
|
|
||||||
|
|
|
@ -420,6 +420,7 @@ typedef enum {
|
||||||
SWITCH_STATUS_MORE_DATA - Need More Data
|
SWITCH_STATUS_MORE_DATA - Need More Data
|
||||||
SWITCH_STATUS_NOTFOUND - Not Found
|
SWITCH_STATUS_NOTFOUND - Not Found
|
||||||
SWITCH_STATUS_UNLOAD - Unload
|
SWITCH_STATUS_UNLOAD - Unload
|
||||||
|
SWITCH_STATUS_NOUNLOAD - Never Unload
|
||||||
</pre>
|
</pre>
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -438,7 +439,8 @@ typedef enum {
|
||||||
SWITCH_STATUS_SOCKERR,
|
SWITCH_STATUS_SOCKERR,
|
||||||
SWITCH_STATUS_MORE_DATA,
|
SWITCH_STATUS_MORE_DATA,
|
||||||
SWITCH_STATUS_NOTFOUND,
|
SWITCH_STATUS_NOTFOUND,
|
||||||
SWITCH_STATUS_UNLOAD
|
SWITCH_STATUS_UNLOAD,
|
||||||
|
SWITCH_STATUS_NOUNLOAD
|
||||||
} switch_status_t;
|
} switch_status_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -816,6 +818,7 @@ typedef enum {
|
||||||
SWITCH_EVENT_NOTALK - Not Talking Detected
|
SWITCH_EVENT_NOTALK - Not Talking Detected
|
||||||
SWITCH_EVENT_SESSION_CRASH - Session Crashed
|
SWITCH_EVENT_SESSION_CRASH - Session Crashed
|
||||||
SWITCH_EVENT_MODULE_LOAD - Module was loaded
|
SWITCH_EVENT_MODULE_LOAD - Module was loaded
|
||||||
|
SWITCH_EVENT_MODULE_UNLOAD - Module was unloaded
|
||||||
SWITCH_EVENT_DTMF - DTMF was sent
|
SWITCH_EVENT_DTMF - DTMF was sent
|
||||||
SWITCH_EVENT_MESSAGE - A Basic Message
|
SWITCH_EVENT_MESSAGE - A Basic Message
|
||||||
SWITCH_EVENT_PRESENCE_IN - Presence in
|
SWITCH_EVENT_PRESENCE_IN - Presence in
|
||||||
|
@ -863,6 +866,7 @@ typedef enum {
|
||||||
SWITCH_EVENT_NOTALK,
|
SWITCH_EVENT_NOTALK,
|
||||||
SWITCH_EVENT_SESSION_CRASH,
|
SWITCH_EVENT_SESSION_CRASH,
|
||||||
SWITCH_EVENT_MODULE_LOAD,
|
SWITCH_EVENT_MODULE_LOAD,
|
||||||
|
SWITCH_EVENT_MODULE_UNLOAD,
|
||||||
SWITCH_EVENT_DTMF,
|
SWITCH_EVENT_DTMF,
|
||||||
SWITCH_EVENT_MESSAGE,
|
SWITCH_EVENT_MESSAGE,
|
||||||
SWITCH_EVENT_PRESENCE_IN,
|
SWITCH_EVENT_PRESENCE_IN,
|
||||||
|
|
|
@ -46,6 +46,7 @@ static switch_api_interface_t show_api_interface;
|
||||||
static switch_api_interface_t pause_api_interface;
|
static switch_api_interface_t pause_api_interface;
|
||||||
static switch_api_interface_t transfer_api_interface;
|
static switch_api_interface_t transfer_api_interface;
|
||||||
static switch_api_interface_t load_api_interface;
|
static switch_api_interface_t load_api_interface;
|
||||||
|
static switch_api_interface_t unload_api_interface;
|
||||||
static switch_api_interface_t reload_api_interface;
|
static switch_api_interface_t reload_api_interface;
|
||||||
static switch_api_interface_t kill_api_interface;
|
static switch_api_interface_t kill_api_interface;
|
||||||
static switch_api_interface_t originate_api_interface;
|
static switch_api_interface_t originate_api_interface;
|
||||||
|
@ -150,6 +151,7 @@ static switch_status_t ctl_function(char *data, switch_core_session_t *session,
|
||||||
|
|
||||||
static switch_status_t load_function(char *mod, switch_core_session_t *session, switch_stream_handle_t *stream)
|
static switch_status_t load_function(char *mod, switch_core_session_t *session, switch_stream_handle_t *stream)
|
||||||
{
|
{
|
||||||
|
const char *err;
|
||||||
|
|
||||||
if (session) {
|
if (session) {
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
|
@ -160,10 +162,32 @@ static switch_status_t load_function(char *mod, switch_core_session_t *session,
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) mod, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
|
if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) mod, SWITCH_TRUE, &err) == SWITCH_STATUS_SUCCESS) {
|
||||||
stream->write_function(stream, "OK\n");
|
stream->write_function(stream, "OK\n");
|
||||||
} else {
|
} else {
|
||||||
stream->write_function(stream, "ERROR\n");
|
stream->write_function(stream, "ERROR [%s]\n", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static switch_status_t unload_function(char *mod, switch_core_session_t *session, switch_stream_handle_t *stream)
|
||||||
|
{
|
||||||
|
const char *err;
|
||||||
|
|
||||||
|
if (session) {
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (switch_strlen_zero(mod)) {
|
||||||
|
stream->write_function(stream, "USAGE: %s\n", unload_api_interface.syntax);
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (switch_loadable_module_unload_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) mod, &err) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
stream->write_function(stream, "OK\n");
|
||||||
|
} else {
|
||||||
|
stream->write_function(stream, "ERROR [%s]\n", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
@ -1221,12 +1245,20 @@ static switch_api_interface_t load_api_interface = {
|
||||||
/*.next */ &transfer_api_interface
|
/*.next */ &transfer_api_interface
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static switch_api_interface_t unload_api_interface = {
|
||||||
|
/*.interface_name */ "unload",
|
||||||
|
/*.desc */ "Unoad Module",
|
||||||
|
/*.function */ unload_function,
|
||||||
|
/*.syntax */ "<mod_name>",
|
||||||
|
/*.next */ &load_api_interface
|
||||||
|
};
|
||||||
|
|
||||||
static switch_api_interface_t reload_api_interface = {
|
static switch_api_interface_t reload_api_interface = {
|
||||||
/*.interface_name */ "reloadxml",
|
/*.interface_name */ "reloadxml",
|
||||||
/*.desc */ "Reload XML",
|
/*.desc */ "Reload XML",
|
||||||
/*.function */ reload_function,
|
/*.function */ reload_function,
|
||||||
/*.syntax */ "",
|
/*.syntax */ "",
|
||||||
/*.next */ &load_api_interface,
|
/*.next */ &unload_api_interface,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1263,7 +1295,7 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod
|
||||||
*module_interface = &mod_commands_module_interface;
|
*module_interface = &mod_commands_module_interface;
|
||||||
|
|
||||||
/* indicate that the module should continue to be loaded */
|
/* indicate that the module should continue to be loaded */
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_NOUNLOAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For Emacs:
|
/* For Emacs:
|
||||||
|
|
|
@ -1565,11 +1565,14 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SWITCH_HAVE_ODBC
|
#ifdef SWITCH_HAVE_ODBC
|
||||||
return profile->master_odbc ? 1 : 0;
|
if (profile->odbc_dsn) {
|
||||||
#else
|
return profile->master_odbc ? 1 : 0;
|
||||||
return 1;
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return profile->master_db ? 1: 0;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sofia_glue_sql_close(sofia_profile_t *profile)
|
void sofia_glue_sql_close(sofia_profile_t *profile)
|
||||||
|
|
|
@ -57,19 +57,83 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_insert_dup(switch_hash_t * hash
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_core_hash_insert_dup_locked(switch_hash_t * hash, const char *key, const void *data, switch_mutex_t *mutex)
|
||||||
|
{
|
||||||
|
if (mutex) {
|
||||||
|
switch_mutex_lock(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
apr_hash_set(hash, switch_core_strdup(apr_hash_pool_get(hash), key), APR_HASH_KEY_STRING, data);
|
||||||
|
|
||||||
|
if (mutex) {
|
||||||
|
switch_mutex_unlock(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_core_hash_insert(switch_hash_t * hash, const char *key, const void *data)
|
SWITCH_DECLARE(switch_status_t) switch_core_hash_insert(switch_hash_t * hash, const char *key, const void *data)
|
||||||
{
|
{
|
||||||
apr_hash_set(hash, key, APR_HASH_KEY_STRING, data);
|
apr_hash_set(hash, key, APR_HASH_KEY_STRING, data);
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_core_hash_insert_locked(switch_hash_t * hash, const char *key, const void *data, switch_mutex_t *mutex)
|
||||||
|
{
|
||||||
|
if (mutex) {
|
||||||
|
switch_mutex_lock(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
apr_hash_set(hash, key, APR_HASH_KEY_STRING, data);
|
||||||
|
|
||||||
|
if (mutex) {
|
||||||
|
switch_mutex_unlock(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_core_hash_delete(switch_hash_t * hash, const char *key)
|
SWITCH_DECLARE(switch_status_t) switch_core_hash_delete(switch_hash_t * hash, const char *key)
|
||||||
{
|
{
|
||||||
apr_hash_set(hash, key, APR_HASH_KEY_STRING, NULL);
|
apr_hash_set(hash, key, APR_HASH_KEY_STRING, NULL);
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_locked(switch_hash_t * hash, const char *key, switch_mutex_t *mutex)
|
||||||
|
{
|
||||||
|
if (mutex) {
|
||||||
|
switch_mutex_lock(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
apr_hash_set(hash, key, APR_HASH_KEY_STRING, NULL);
|
||||||
|
|
||||||
|
if (mutex) {
|
||||||
|
switch_mutex_unlock(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SWITCH_DECLARE(void *) switch_core_hash_find(switch_hash_t * hash, const char *key)
|
SWITCH_DECLARE(void *) switch_core_hash_find(switch_hash_t * hash, const char *key)
|
||||||
{
|
{
|
||||||
return apr_hash_get(hash, key, APR_HASH_KEY_STRING);
|
return apr_hash_get(hash, key, APR_HASH_KEY_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(void *) switch_core_hash_find_locked(switch_hash_t * hash, const char *key, switch_mutex_t *mutex)
|
||||||
|
{
|
||||||
|
void *val;
|
||||||
|
|
||||||
|
if (mutex) {
|
||||||
|
switch_mutex_lock(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
val = apr_hash_get(hash, key, APR_HASH_KEY_STRING);
|
||||||
|
|
||||||
|
if (mutex) {
|
||||||
|
switch_mutex_unlock(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
|
@ -121,6 +121,7 @@ static char *EVENT_NAMES[] = {
|
||||||
"NOTALK",
|
"NOTALK",
|
||||||
"SESSION_CRASH",
|
"SESSION_CRASH",
|
||||||
"MODULE_LOAD",
|
"MODULE_LOAD",
|
||||||
|
"MODULE_UNLOAD",
|
||||||
"DTMF",
|
"DTMF",
|
||||||
"MESSAGE",
|
"MESSAGE",
|
||||||
"PRESENCE_IN",
|
"PRESENCE_IN",
|
||||||
|
|
|
@ -41,12 +41,15 @@
|
||||||
#include <apr_file_io.h>
|
#include <apr_file_io.h>
|
||||||
|
|
||||||
struct switch_loadable_module {
|
struct switch_loadable_module {
|
||||||
|
char *key;
|
||||||
char *filename;
|
char *filename;
|
||||||
|
int perm;
|
||||||
const switch_loadable_module_interface_t *module_interface;
|
const switch_loadable_module_interface_t *module_interface;
|
||||||
void *lib;
|
void *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;
|
||||||
|
switch_memory_pool_t *pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct switch_loadable_module_container {
|
struct switch_loadable_module_container {
|
||||||
|
@ -64,10 +67,12 @@ struct switch_loadable_module_container {
|
||||||
switch_hash_t *chat_hash;
|
switch_hash_t *chat_hash;
|
||||||
switch_hash_t *say_hash;
|
switch_hash_t *say_hash;
|
||||||
switch_hash_t *management_hash;
|
switch_hash_t *management_hash;
|
||||||
|
switch_mutex_t *mutex;
|
||||||
switch_memory_pool_t *pool;
|
switch_memory_pool_t *pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
static void *switch_loadable_module_exec(switch_thread_t * thread, void *obj)
|
static void *switch_loadable_module_exec(switch_thread_t * thread, void *obj)
|
||||||
{
|
{
|
||||||
|
@ -102,6 +107,7 @@ static void switch_loadable_module_runtime(void)
|
||||||
void *val;
|
void *val;
|
||||||
switch_loadable_module_t *module;
|
switch_loadable_module_t *module;
|
||||||
|
|
||||||
|
switch_mutex_lock(loadable_modules.mutex);
|
||||||
for (hi = switch_hash_first(loadable_modules.pool, loadable_modules.module_hash); hi; hi = switch_hash_next(hi)) {
|
for (hi = switch_hash_first(loadable_modules.pool, loadable_modules.module_hash); hi; hi = switch_hash_next(hi)) {
|
||||||
switch_hash_this(hi, NULL, NULL, &val);
|
switch_hash_this(hi, NULL, NULL, &val);
|
||||||
module = (switch_loadable_module_t *) val;
|
module = (switch_loadable_module_t *) val;
|
||||||
|
@ -111,12 +117,16 @@ static void switch_loadable_module_runtime(void)
|
||||||
switch_core_launch_thread(switch_loadable_module_exec, module, loadable_modules.pool);
|
switch_core_launch_thread(switch_loadable_module_exec, module, loadable_modules.pool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
switch_mutex_unlock(loadable_modules.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static switch_status_t switch_loadable_module_process(char *key, switch_loadable_module_t *new_module)
|
static switch_status_t switch_loadable_module_process(char *key, switch_loadable_module_t *new_module)
|
||||||
{
|
{
|
||||||
switch_event_t *event;
|
switch_event_t *event;
|
||||||
|
|
||||||
|
new_module->key = switch_core_strdup(new_module->pool, key);
|
||||||
|
|
||||||
|
switch_mutex_lock(loadable_modules.mutex);
|
||||||
switch_core_hash_insert(loadable_modules.module_hash, key, new_module);
|
switch_core_hash_insert(loadable_modules.module_hash, key, new_module);
|
||||||
|
|
||||||
if (new_module->module_interface->endpoint_interface) {
|
if (new_module->module_interface->endpoint_interface) {
|
||||||
|
@ -380,11 +390,252 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_mutex_unlock(loadable_modules.mutex);
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t *old_module)
|
||||||
|
{
|
||||||
|
switch_event_t *event;
|
||||||
|
|
||||||
|
switch_mutex_lock(loadable_modules.mutex);
|
||||||
|
switch_core_hash_delete(loadable_modules.module_hash, old_module->key);
|
||||||
|
|
||||||
|
if (old_module->module_interface->endpoint_interface) {
|
||||||
|
const switch_endpoint_interface_t *ptr;
|
||||||
|
for (ptr = old_module->module_interface->endpoint_interface; ptr; ptr = ptr->next) {
|
||||||
|
if (ptr->interface_name) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Endpoint '%s'\n", ptr->interface_name);
|
||||||
|
switch_core_hash_delete(loadable_modules.endpoint_hash, ptr->interface_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_module->module_interface->codec_interface) {
|
||||||
|
const switch_codec_implementation_t *impl;
|
||||||
|
const switch_codec_interface_t *ptr;
|
||||||
|
|
||||||
|
for (ptr = old_module->module_interface->codec_interface; ptr; ptr = ptr->next) {
|
||||||
|
if (ptr->interface_name) {
|
||||||
|
unsigned load_interface = 1;
|
||||||
|
for (impl = ptr->implementations; impl; impl = impl->next) {
|
||||||
|
if (!impl->iananame) {
|
||||||
|
load_interface = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (load_interface) {
|
||||||
|
for (impl = ptr->implementations; impl; impl = impl->next) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,
|
||||||
|
"Deleting Codec '%s' (%s) %dhz %dms\n",
|
||||||
|
impl->iananame, ptr->interface_name, impl->samples_per_second, impl->microseconds_per_frame / 1000);
|
||||||
|
if (switch_core_hash_find(loadable_modules.codec_hash, impl->iananame)) {
|
||||||
|
switch_core_hash_delete(loadable_modules.codec_hash, impl->iananame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "type", "codec");
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "name", "%s", ptr->interface_name);
|
||||||
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_module->module_interface->dialplan_interface) {
|
||||||
|
const switch_dialplan_interface_t *ptr;
|
||||||
|
|
||||||
|
for (ptr = old_module->module_interface->dialplan_interface; ptr; ptr = ptr->next) {
|
||||||
|
if (ptr->interface_name) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Dialplan '%s'\n", ptr->interface_name);
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "type", "dialplan");
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "name", "%s", ptr->interface_name);
|
||||||
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
switch_core_hash_delete(loadable_modules.dialplan_hash, ptr->interface_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_module->module_interface->timer_interface) {
|
||||||
|
const switch_timer_interface_t *ptr;
|
||||||
|
|
||||||
|
for (ptr = old_module->module_interface->timer_interface; ptr; ptr = ptr->next) {
|
||||||
|
if (ptr->interface_name) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Timer '%s'\n", ptr->interface_name);
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "type", "timer");
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "name", "%s", ptr->interface_name);
|
||||||
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
switch_core_hash_delete(loadable_modules.timer_hash, ptr->interface_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_module->module_interface->application_interface) {
|
||||||
|
const switch_application_interface_t *ptr;
|
||||||
|
|
||||||
|
for (ptr = old_module->module_interface->application_interface; ptr; ptr = ptr->next) {
|
||||||
|
if (ptr->interface_name) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Application '%s'\n", ptr->interface_name);
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "type", "application");
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "name", "%s", ptr->interface_name);
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "description", "%s", switch_str_nil(ptr->short_desc));
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "syntax", "%s", switch_str_nil(ptr->syntax));
|
||||||
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
switch_core_hash_delete(loadable_modules.application_hash, ptr->interface_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_module->module_interface->api_interface) {
|
||||||
|
const switch_api_interface_t *ptr;
|
||||||
|
|
||||||
|
for (ptr = old_module->module_interface->api_interface; ptr; ptr = ptr->next) {
|
||||||
|
if (ptr->interface_name) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting API Function '%s'\n", ptr->interface_name);
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "type", "api");
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "name", "%s", ptr->interface_name);
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "description", "%s", switch_str_nil(ptr->desc));
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "syntax", "%s", switch_str_nil(ptr->syntax));
|
||||||
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
switch_core_hash_delete(loadable_modules.api_hash, ptr->interface_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_module->module_interface->file_interface) {
|
||||||
|
const switch_file_interface_t *ptr;
|
||||||
|
|
||||||
|
for (ptr = old_module->module_interface->file_interface; ptr; ptr = ptr->next) {
|
||||||
|
if (ptr->interface_name) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; ptr->extens[i]; i++) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting File Format '%s'\n", ptr->extens[i]);
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "type", "file");
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "name", "%s", ptr->extens[i]);
|
||||||
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
switch_core_hash_delete(loadable_modules.file_hash, ptr->extens[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_module->module_interface->speech_interface) {
|
||||||
|
const switch_speech_interface_t *ptr;
|
||||||
|
|
||||||
|
for (ptr = old_module->module_interface->speech_interface; ptr; ptr = ptr->next) {
|
||||||
|
if (ptr->interface_name) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Speech interface '%s'\n", ptr->interface_name);
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "type", "speech");
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "name", "%s", ptr->interface_name);
|
||||||
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
switch_core_hash_delete(loadable_modules.speech_hash, ptr->interface_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_module->module_interface->asr_interface) {
|
||||||
|
const switch_asr_interface_t *ptr;
|
||||||
|
|
||||||
|
for (ptr = old_module->module_interface->asr_interface; ptr; ptr = ptr->next) {
|
||||||
|
if (ptr->interface_name) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Asr interface '%s'\n", ptr->interface_name);
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "type", "asr");
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "name", "%s", ptr->interface_name);
|
||||||
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
switch_core_hash_delete(loadable_modules.asr_hash, ptr->interface_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_module->module_interface->directory_interface) {
|
||||||
|
const switch_directory_interface_t *ptr;
|
||||||
|
|
||||||
|
for (ptr = old_module->module_interface->directory_interface; ptr; ptr = ptr->next) {
|
||||||
|
if (ptr->interface_name) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Directory interface '%s'\n", ptr->interface_name);
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "type", "directory");
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "name", "%s", ptr->interface_name);
|
||||||
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
switch_core_hash_delete(loadable_modules.directory_hash, ptr->interface_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (old_module->module_interface->chat_interface) {
|
||||||
|
const switch_chat_interface_t *ptr;
|
||||||
|
|
||||||
|
for (ptr = old_module->module_interface->chat_interface; ptr; ptr = ptr->next) {
|
||||||
|
if (ptr->interface_name) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Chat interface '%s'\n", ptr->interface_name);
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "type", "chat");
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "name", "%s", ptr->interface_name);
|
||||||
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
switch_core_hash_delete(loadable_modules.chat_hash, ptr->interface_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_module->module_interface->say_interface) {
|
||||||
|
const switch_say_interface_t *ptr;
|
||||||
|
|
||||||
|
for (ptr = old_module->module_interface->say_interface; ptr; ptr = ptr->next) {
|
||||||
|
if (ptr->interface_name) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Say interface '%s'\n", ptr->interface_name);
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "type", "say");
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "name", "%s", ptr->interface_name);
|
||||||
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
switch_core_hash_delete(loadable_modules.say_hash, ptr->interface_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_module->module_interface->management_interface) {
|
||||||
|
const switch_management_interface_t *ptr;
|
||||||
|
|
||||||
|
for (ptr = old_module->module_interface->management_interface; ptr; ptr = ptr->next) {
|
||||||
|
if (ptr->relative_oid) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,
|
||||||
|
"Deleting Management interface '%s' OID[%s.%s]\n", old_module->key, FREESWITCH_OID_PREFIX, ptr->relative_oid);
|
||||||
|
switch_core_hash_delete(loadable_modules.management_hash, ptr->relative_oid);
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "type", "management");
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "name", "%s", ptr->relative_oid);
|
||||||
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch_mutex_unlock(loadable_modules.mutex);
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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 *filename, switch_loadable_module_t **new_module)
|
||||||
{
|
{
|
||||||
switch_loadable_module_t *module = NULL;
|
switch_loadable_module_t *module = NULL;
|
||||||
|
@ -398,12 +649,18 @@ static switch_status_t switch_loadable_module_load_file(char *filename, switch_l
|
||||||
const char *err = NULL;
|
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[512] = "";
|
||||||
|
switch_memory_pool_t *pool;
|
||||||
|
|
||||||
assert(filename != NULL);
|
assert(filename != NULL);
|
||||||
|
|
||||||
*new_module = NULL;
|
*new_module = NULL;
|
||||||
status = switch_dso_load(&dso, filename, loadable_modules.pool);
|
status = switch_dso_load(&dso, filename, 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");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
while (loading) {
|
while (loading) {
|
||||||
if (status != APR_SUCCESS) {
|
if (status != APR_SUCCESS) {
|
||||||
switch_dso_error(dso, derr, sizeof(derr));
|
switch_dso_error(dso, derr, sizeof(derr));
|
||||||
|
@ -419,26 +676,37 @@ static switch_status_t switch_loadable_module_load_file(char *filename, switch_l
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (load_func_ptr(&module_interface, filename) != SWITCH_STATUS_SUCCESS) {
|
status = load_func_ptr(&module_interface, filename);
|
||||||
|
|
||||||
|
if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_NOUNLOAD) {
|
||||||
err = "Module load routine returned an error";
|
err = "Module load routine returned an error";
|
||||||
module_interface = NULL;
|
module_interface = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((module = switch_core_permanent_alloc(sizeof(switch_loadable_module_t))) == 0) {
|
if ((module = switch_core_alloc(pool, sizeof(switch_loadable_module_t))) == 0) {
|
||||||
err = "Could not allocate memory\n";
|
err = "Could not allocate memory\n";
|
||||||
break;
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status == SWITCH_STATUS_NOUNLOAD) {
|
||||||
|
module->perm++;
|
||||||
|
}
|
||||||
|
|
||||||
loading = 0;
|
loading = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
|
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", filename, err);
|
||||||
return SWITCH_STATUS_GENERR;
|
return SWITCH_STATUS_GENERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
module->filename = switch_core_permanent_strdup(filename);
|
module->pool = pool;
|
||||||
|
module->filename = switch_core_strdup(module->pool, filename);
|
||||||
module->module_interface = module_interface;
|
module->module_interface = module_interface;
|
||||||
module->switch_module_load = load_func_ptr;
|
module->switch_module_load = load_func_ptr;
|
||||||
|
|
||||||
|
@ -456,7 +724,7 @@ static switch_status_t switch_loadable_module_load_file(char *filename, switch_l
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_loadable_module_load_module(char *dir, char *fname, switch_bool_t runtime)
|
SWITCH_DECLARE(switch_status_t) switch_loadable_module_load_module(char *dir, char *fname, switch_bool_t runtime, const char **err)
|
||||||
{
|
{
|
||||||
switch_size_t len = 0;
|
switch_size_t len = 0;
|
||||||
char *path;
|
char *path;
|
||||||
|
@ -495,18 +763,82 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_load_module(char *dir, ch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_mutex_lock(loadable_modules.mutex);
|
||||||
if (switch_core_hash_find(loadable_modules.module_hash, file)) {
|
if (switch_core_hash_find(loadable_modules.module_hash, file)) {
|
||||||
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);
|
||||||
return SWITCH_STATUS_FALSE;
|
*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_load_file(path, &new_module) == SWITCH_STATUS_SUCCESS)) {
|
|
||||||
if ((status = switch_loadable_module_process((char *) file, new_module)) == SWITCH_STATUS_SUCCESS && runtime) {
|
if ((status = switch_loadable_module_process((char *) 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, loadable_modules.pool);
|
switch_core_launch_thread(switch_loadable_module_exec, new_module, new_module->pool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
switch_mutex_unlock(loadable_modules.mutex);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_loadable_module_unload_module(char *dir, char *fname, const char **err)
|
||||||
|
{
|
||||||
|
switch_size_t len = 0;
|
||||||
|
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, '.')) {
|
||||||
|
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 *) malloc(len);
|
||||||
|
snprintf(path, len, "%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->perm) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Module is not unloadable.\n");
|
||||||
|
*err = "Module is not unloadable";
|
||||||
|
status = SWITCH_STATUS_NOUNLOAD;
|
||||||
|
} else {
|
||||||
|
do_shutdown(module);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
status = SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
switch_mutex_unlock(loadable_modules.mutex);
|
||||||
|
|
||||||
|
switch_safe_free(file);
|
||||||
|
switch_safe_free(path);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
@ -522,40 +854,58 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_build_dynamic(char *filen
|
||||||
int loading = 1;
|
int loading = 1;
|
||||||
const char *err = NULL;
|
const char *err = NULL;
|
||||||
switch_loadable_module_interface_t *module_interface = NULL;
|
switch_loadable_module_interface_t *module_interface = NULL;
|
||||||
|
switch_memory_pool_t *pool;
|
||||||
|
|
||||||
if ((module = switch_core_permanent_alloc(sizeof(switch_loadable_module_t))) == 0) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Couldn't allocate memory\n");
|
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
|
||||||
return SWITCH_STATUS_GENERR;
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((module = switch_core_alloc(pool, sizeof(switch_loadable_module_t))) == 0) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Couldn't allocate memory\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
while (loading) {
|
while (loading) {
|
||||||
load_func_ptr = (switch_module_load_t) switch_module_load;
|
load_func_ptr = (switch_module_load_t) switch_module_load;
|
||||||
|
switch_status_t status;
|
||||||
|
|
||||||
if (load_func_ptr == NULL) {
|
if (load_func_ptr == NULL) {
|
||||||
err = "Cannot Load";
|
err = "Cannot Load";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (load_func_ptr(&module_interface, filename) != SWITCH_STATUS_SUCCESS) {
|
status = load_func_ptr(&module_interface, filename);
|
||||||
|
|
||||||
|
if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_NOUNLOAD) {
|
||||||
err = "Module load routine returned an error";
|
err = "Module load routine returned an error";
|
||||||
module_interface = NULL;
|
module_interface = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((module = switch_core_permanent_alloc(sizeof(switch_loadable_module_t))) == 0) {
|
if ((module = switch_core_alloc(pool, sizeof(switch_loadable_module_t))) == 0) {
|
||||||
err = "Could not allocate memory\n";
|
err = "Could not allocate memory\n";
|
||||||
break;
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == SWITCH_STATUS_NOUNLOAD) {
|
||||||
|
module->perm++;
|
||||||
}
|
}
|
||||||
|
|
||||||
loading = 0;
|
loading = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
|
switch_core_destroy_memory_pool(&pool);
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Error Loading module %s\n**%s**\n", filename, err);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Error Loading module %s\n**%s**\n", filename, err);
|
||||||
return SWITCH_STATUS_GENERR;
|
return SWITCH_STATUS_GENERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
module->filename = switch_core_permanent_strdup(filename);
|
module->pool = pool;
|
||||||
|
module->filename = switch_core_strdup(module->pool, filename);
|
||||||
module->module_interface = module_interface;
|
module->module_interface = module_interface;
|
||||||
module->switch_module_load = load_func_ptr;
|
module->switch_module_load = load_func_ptr;
|
||||||
|
|
||||||
|
@ -566,7 +916,7 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_build_dynamic(char *filen
|
||||||
module->switch_module_runtime = switch_module_runtime;
|
module->switch_module_runtime = switch_module_runtime;
|
||||||
}
|
}
|
||||||
if (module->switch_module_runtime) {
|
if (module->switch_module_runtime) {
|
||||||
switch_core_launch_thread(switch_loadable_module_exec, module, loadable_modules.pool);
|
switch_core_launch_thread(switch_loadable_module_exec, module, module->pool);
|
||||||
}
|
}
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Successfully Loaded [%s]\n", module_interface->module_name);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Successfully Loaded [%s]\n", module_interface->module_name);
|
||||||
return switch_loadable_module_process((char *) module->filename, module);
|
return switch_loadable_module_process((char *) module->filename, module);
|
||||||
|
@ -599,6 +949,8 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init()
|
||||||
switch_xml_t cfg, xml;
|
switch_xml_t cfg, xml;
|
||||||
unsigned char all = 0;
|
unsigned char all = 0;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
|
const char *err;
|
||||||
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
const char *ext = ".dll";
|
const char *ext = ".dll";
|
||||||
|
@ -633,10 +985,10 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init()
|
||||||
switch_core_hash_init(&loadable_modules.say_hash, loadable_modules.pool);
|
switch_core_hash_init(&loadable_modules.say_hash, loadable_modules.pool);
|
||||||
switch_core_hash_init(&loadable_modules.management_hash, loadable_modules.pool);
|
switch_core_hash_init(&loadable_modules.management_hash, loadable_modules.pool);
|
||||||
switch_core_hash_init(&loadable_modules.dialplan_hash, loadable_modules.pool);
|
switch_core_hash_init(&loadable_modules.dialplan_hash, loadable_modules.pool);
|
||||||
|
switch_mutex_init(&loadable_modules.mutex, SWITCH_MUTEX_NESTED, loadable_modules.pool);
|
||||||
|
|
||||||
if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
|
if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
|
||||||
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) {
|
||||||
const char *val = switch_xml_attr_soft(ld, "module");
|
const char *val = switch_xml_attr_soft(ld, "module");
|
||||||
|
@ -644,7 +996,7 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init()
|
||||||
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);
|
switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) val, SWITCH_FALSE, &err);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -664,7 +1016,7 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init()
|
||||||
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);
|
switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) val, SWITCH_FALSE, &err);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -687,6 +1039,7 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init()
|
||||||
|
|
||||||
while (apr_dir_read(&finfo, finfo_flags, module_dir_handle) == APR_SUCCESS) {
|
while (apr_dir_read(&finfo, finfo_flags, module_dir_handle) == APR_SUCCESS) {
|
||||||
const char *fname = finfo.fname;
|
const char *fname = finfo.fname;
|
||||||
|
const char *err;
|
||||||
|
|
||||||
if (finfo.filetype != APR_REG) {
|
if (finfo.filetype != APR_REG) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -704,7 +1057,7 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) fname, SWITCH_FALSE);
|
switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) fname, SWITCH_FALSE, &err);
|
||||||
}
|
}
|
||||||
apr_dir_close(module_dir_handle);
|
apr_dir_close(module_dir_handle);
|
||||||
}
|
}
|
||||||
|
@ -714,35 +1067,58 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init()
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void do_shutdown(switch_loadable_module_t *module)
|
||||||
|
{
|
||||||
|
assert(module != NULL);
|
||||||
|
|
||||||
|
switch_loadable_module_unprocess(module);
|
||||||
|
|
||||||
|
if (module->switch_module_shutdown) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Stopping: %s\n", module->module_interface->module_name);
|
||||||
|
if (module->switch_module_shutdown() == SWITCH_STATUS_UNLOAD) {
|
||||||
|
switch_memory_pool_t *pool;
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s unloaded.\n", module->module_interface->module_name);
|
||||||
|
switch_dso_unload(module->lib);
|
||||||
|
module->lib = NULL;
|
||||||
|
if ((pool = module->pool)) {
|
||||||
|
module = NULL;
|
||||||
|
switch_core_destroy_memory_pool(&pool);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s shutdown.\n", module->module_interface->module_name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s has no shutdown routine\n", module->module_interface->module_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
switch_core_hash_delete_locked(loadable_modules.module_hash, module->key, loadable_modules.mutex);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(void) switch_loadable_module_shutdown(void)
|
SWITCH_DECLARE(void) switch_loadable_module_shutdown(void)
|
||||||
{
|
{
|
||||||
switch_hash_index_t *hi;
|
switch_hash_index_t *hi;
|
||||||
void *val;
|
void *val;
|
||||||
switch_loadable_module_t *module;
|
switch_loadable_module_t *module;
|
||||||
|
|
||||||
for (hi = switch_hash_first(loadable_modules.pool, loadable_modules.module_hash); hi; hi = switch_hash_next(hi)) {
|
for (hi = switch_hash_first(loadable_modules.pool, loadable_modules.module_hash); hi; hi = switch_hash_next(hi)) {
|
||||||
switch_hash_this(hi, NULL, NULL, &val);
|
switch_hash_this(hi, NULL, NULL, &val);
|
||||||
module = (switch_loadable_module_t *) val;
|
module = (switch_loadable_module_t *) val;
|
||||||
|
do_shutdown(module);
|
||||||
if (module->switch_module_shutdown) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Stopping: %s\n", module->module_interface->module_name);
|
|
||||||
if (module->switch_module_shutdown() == SWITCH_STATUS_UNLOAD) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s unloaded.\n", module->module_interface->module_name);
|
|
||||||
switch_dso_unload(module->lib);
|
|
||||||
module->lib = NULL;
|
|
||||||
} else {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s shutdown.\n", module->module_interface->module_name);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s has no shutdown routine\n", module->module_interface->module_name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_endpoint_interface_t *) switch_loadable_module_get_endpoint_interface(char *name)
|
SWITCH_DECLARE(switch_endpoint_interface_t *) switch_loadable_module_get_endpoint_interface(char *name)
|
||||||
{
|
{
|
||||||
return switch_core_hash_find(loadable_modules.endpoint_hash, name);
|
switch_endpoint_interface_t *ptr;
|
||||||
|
|
||||||
|
switch_mutex_lock(loadable_modules.mutex);
|
||||||
|
ptr = switch_core_hash_find(loadable_modules.endpoint_hash, name);
|
||||||
|
switch_mutex_unlock(loadable_modules.mutex);
|
||||||
|
|
||||||
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_codec_interface_t *) switch_loadable_module_get_codec_interface(char *name)
|
SWITCH_DECLARE(switch_codec_interface_t *) switch_loadable_module_get_codec_interface(char *name)
|
||||||
|
@ -751,6 +1127,7 @@ SWITCH_DECLARE(switch_codec_interface_t *) switch_loadable_module_get_codec_inte
|
||||||
switch_codec_interface_t *codec;
|
switch_codec_interface_t *codec;
|
||||||
switch_size_t x;
|
switch_size_t x;
|
||||||
|
|
||||||
|
switch_mutex_lock(loadable_modules.mutex);
|
||||||
if (!(codec = switch_core_hash_find(loadable_modules.codec_hash, name))) {
|
if (!(codec = switch_core_hash_find(loadable_modules.codec_hash, name))) {
|
||||||
for (x = 0; x < strlen(name); x++) {
|
for (x = 0; x < strlen(name); x++) {
|
||||||
altname[x] = (char) toupper((int) name[x]);
|
altname[x] = (char) toupper((int) name[x]);
|
||||||
|
@ -762,62 +1139,63 @@ SWITCH_DECLARE(switch_codec_interface_t *) switch_loadable_module_get_codec_inte
|
||||||
codec = switch_core_hash_find(loadable_modules.codec_hash, altname);
|
codec = switch_core_hash_find(loadable_modules.codec_hash, altname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
switch_mutex_unlock(loadable_modules.mutex);
|
||||||
return codec;
|
return codec;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_dialplan_interface_t *) switch_loadable_module_get_dialplan_interface(char *name)
|
SWITCH_DECLARE(switch_dialplan_interface_t *) switch_loadable_module_get_dialplan_interface(char *name)
|
||||||
{
|
{
|
||||||
return switch_core_hash_find(loadable_modules.dialplan_hash, name);
|
return switch_core_hash_find_locked(loadable_modules.dialplan_hash, name, loadable_modules.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_timer_interface_t *) switch_loadable_module_get_timer_interface(char *name)
|
SWITCH_DECLARE(switch_timer_interface_t *) switch_loadable_module_get_timer_interface(char *name)
|
||||||
{
|
{
|
||||||
return switch_core_hash_find(loadable_modules.timer_hash, name);
|
return switch_core_hash_find_locked(loadable_modules.timer_hash, name, loadable_modules.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_application_interface_t *) switch_loadable_module_get_application_interface(char *name)
|
SWITCH_DECLARE(switch_application_interface_t *) switch_loadable_module_get_application_interface(char *name)
|
||||||
{
|
{
|
||||||
return switch_core_hash_find(loadable_modules.application_hash, name);
|
return switch_core_hash_find_locked(loadable_modules.application_hash, name, loadable_modules.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_api_interface_t *) switch_loadable_module_get_api_interface(char *name)
|
SWITCH_DECLARE(switch_api_interface_t *) switch_loadable_module_get_api_interface(char *name)
|
||||||
{
|
{
|
||||||
return switch_core_hash_find(loadable_modules.api_hash, name);
|
return switch_core_hash_find_locked(loadable_modules.api_hash, name, loadable_modules.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_file_interface_t *) switch_loadable_module_get_file_interface(char *name)
|
SWITCH_DECLARE(switch_file_interface_t *) switch_loadable_module_get_file_interface(char *name)
|
||||||
{
|
{
|
||||||
return switch_core_hash_find(loadable_modules.file_hash, name);
|
return switch_core_hash_find_locked(loadable_modules.file_hash, name, loadable_modules.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_speech_interface_t *) switch_loadable_module_get_speech_interface(char *name)
|
SWITCH_DECLARE(switch_speech_interface_t *) switch_loadable_module_get_speech_interface(char *name)
|
||||||
{
|
{
|
||||||
return switch_core_hash_find(loadable_modules.speech_hash, name);
|
return switch_core_hash_find_locked(loadable_modules.speech_hash, name, loadable_modules.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_asr_interface_t *) switch_loadable_module_get_asr_interface(char *name)
|
SWITCH_DECLARE(switch_asr_interface_t *) switch_loadable_module_get_asr_interface(char *name)
|
||||||
{
|
{
|
||||||
return switch_core_hash_find(loadable_modules.asr_hash, name);
|
return switch_core_hash_find_locked(loadable_modules.asr_hash, name, loadable_modules.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_directory_interface_t *) switch_loadable_module_get_directory_interface(char *name)
|
SWITCH_DECLARE(switch_directory_interface_t *) switch_loadable_module_get_directory_interface(char *name)
|
||||||
{
|
{
|
||||||
return switch_core_hash_find(loadable_modules.directory_hash, name);
|
return switch_core_hash_find_locked(loadable_modules.directory_hash, name, loadable_modules.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_chat_interface_t *) switch_loadable_module_get_chat_interface(char *name)
|
SWITCH_DECLARE(switch_chat_interface_t *) switch_loadable_module_get_chat_interface(char *name)
|
||||||
{
|
{
|
||||||
return switch_core_hash_find(loadable_modules.chat_hash, name);
|
return switch_core_hash_find_locked(loadable_modules.chat_hash, name, loadable_modules.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_say_interface_t *) switch_loadable_module_get_say_interface(char *name)
|
SWITCH_DECLARE(switch_say_interface_t *) switch_loadable_module_get_say_interface(char *name)
|
||||||
{
|
{
|
||||||
return switch_core_hash_find(loadable_modules.say_hash, name);
|
return switch_core_hash_find_locked(loadable_modules.say_hash, name, loadable_modules.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_management_interface_t *) switch_loadable_module_get_management_interface(char *relative_oid)
|
SWITCH_DECLARE(switch_management_interface_t *) switch_loadable_module_get_management_interface(char *relative_oid)
|
||||||
{
|
{
|
||||||
return switch_core_hash_find(loadable_modules.management_hash, relative_oid);
|
return switch_core_hash_find_locked(loadable_modules.management_hash, relative_oid, loadable_modules.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(int) switch_loadable_module_get_codecs(switch_memory_pool_t *pool, const switch_codec_implementation_t **array, int arraylen)
|
SWITCH_DECLARE(int) switch_loadable_module_get_codecs(switch_memory_pool_t *pool, const switch_codec_implementation_t **array, int arraylen)
|
||||||
|
@ -828,6 +1206,7 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs(switch_memory_pool_t *pool
|
||||||
int i = 0;
|
int i = 0;
|
||||||
const switch_codec_implementation_t *imp;
|
const switch_codec_implementation_t *imp;
|
||||||
|
|
||||||
|
switch_mutex_lock(loadable_modules.mutex);
|
||||||
for (hi = switch_hash_first(pool, loadable_modules.codec_hash); hi; hi = switch_hash_next(hi)) {
|
for (hi = switch_hash_first(pool, loadable_modules.codec_hash); hi; hi = switch_hash_next(hi)) {
|
||||||
switch_hash_this(hi, NULL, NULL, &val);
|
switch_hash_this(hi, NULL, NULL, &val);
|
||||||
codec_interface = (switch_codec_interface_t *) val;
|
codec_interface = (switch_codec_interface_t *) val;
|
||||||
|
@ -848,6 +1227,8 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs(switch_memory_pool_t *pool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_mutex_unlock(loadable_modules.mutex);
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -858,6 +1239,8 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_
|
||||||
switch_codec_interface_t *codec_interface;
|
switch_codec_interface_t *codec_interface;
|
||||||
const switch_codec_implementation_t *imp;
|
const switch_codec_implementation_t *imp;
|
||||||
|
|
||||||
|
switch_mutex_lock(loadable_modules.mutex);
|
||||||
|
|
||||||
for (x = 0; x < preflen; x++) {
|
for (x = 0; x < preflen; x++) {
|
||||||
char *cur, *last = NULL, *next = NULL, *name, *p, buf[256];
|
char *cur, *last = NULL, *next = NULL, *name, *p, buf[256];
|
||||||
uint32_t interval = 0, rate = 0;
|
uint32_t interval = 0, rate = 0;
|
||||||
|
@ -930,6 +1313,9 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_mutex_unlock(loadable_modules.mutex);
|
||||||
|
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue