From ffb989e435a969e0a559ff8bd58a215ac176715d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 29 Sep 2007 01:06:08 +0000 Subject: [PATCH] tear the hell out of everything and rip it up into itsy bitsy pieces and put it all back together git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5765 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/private/switch_core_pvt.h | 6 +- src/include/switch.h | 2 + src/include/switch_apr.h | 12 +- src/include/switch_channel.h | 13 +- src/include/switch_console.h | 17 +- src/include/switch_core.h | 43 ++- src/include/switch_event.h | 2 + src/include/switch_types.h | 14 +- .../applications/mod_commands/mod_commands.c | 73 ++--- .../mod_conference/mod_conference.c | 1 + src/mod/applications/mod_enum/mod_enum.c | 18 +- .../mod_dialplan_xml/mod_dialplan_xml.c | 9 +- src/mod/endpoints/mod_alsa/mod_alsa.c | 1 + .../endpoints/mod_dingaling/mod_dingaling.c | 1 + .../endpoints/mod_portaudio/mod_portaudio.c | 1 + src/mod/endpoints/mod_sofia/mod_sofia.c | 11 + src/mod/endpoints/mod_sofia/mod_sofia.h | 1 - src/mod/endpoints/mod_sofia/sofia.c | 78 +++--- src/mod/endpoints/mod_sofia/sofia_glue.c | 48 +--- src/mod/endpoints/mod_sofia/sofia_presence.c | 7 +- src/mod/endpoints/mod_wanpipe/mod_wanpipe.c | 9 +- .../mod_event_multicast/mod_event_multicast.c | 1 + .../mod_event_socket/mod_event_socket.c | 83 +++--- .../mod_local_stream/mod_local_stream.c | 1 + src/mod/formats/mod_sndfile/mod_sndfile.c | 9 +- src/mod/languages/mod_mono/mod_mono.c | 1 + .../mod_spidermonkey/mod_spidermonkey.c | 2 + src/mod/loggers/mod_console/mod_console.c | 27 +- src/switch.c | 10 +- src/switch_apr.c | 24 +- src/switch_caller.c | 98 ++++--- src/switch_channel.c | 108 ++++---- src/switch_core.c | 57 ++-- src/switch_core_hash.c | 92 ++++--- src/switch_core_memory.c | 258 +++++++++++++++--- src/switch_core_session.c | 27 +- src/switch_core_sqldb.c | 2 +- src/switch_core_state_machine.c | 25 +- src/switch_event.c | 47 +++- src/switch_ivr.c | 76 +++--- src/switch_ivr_originate.c | 46 ++-- src/switch_loadable_module.c | 57 ++-- 42 files changed, 886 insertions(+), 532 deletions(-) diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 9211a4d3d0..b7c698f6a3 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -151,9 +151,7 @@ struct switch_runtime { FILE *console; uint8_t running; char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - uint32_t no_new_sessions; - uint32_t shutting_down; - uint32_t crash_prot; + uint32_t flags; }; extern struct switch_runtime runtime; @@ -161,5 +159,7 @@ extern struct switch_runtime runtime; void switch_core_sqldb_start(switch_memory_pool_t *pool); void switch_core_sqldb_stop(void); void switch_core_session_init(switch_memory_pool_t *pool); +void switch_core_session_uninit(void); void switch_core_state_machine_init(switch_memory_pool_t *pool); switch_memory_pool_t *switch_core_memory_init(void); +void switch_core_memory_stop(void); diff --git a/src/include/switch.h b/src/include/switch.h index 5f56f24dbe..9014057520 100644 --- a/src/include/switch.h +++ b/src/include/switch.h @@ -43,6 +43,8 @@ #define SWITCH_END_EXTERN_C #endif + + #ifndef WIN32 #include #endif diff --git a/src/include/switch_apr.h b/src/include/switch_apr.h index d11a9db32a..1442131a20 100644 --- a/src/include/switch_apr.h +++ b/src/include/switch_apr.h @@ -133,6 +133,7 @@ SWITCH_DECLARE(char *) switch_copy_string(char *dst, const char *src, switch_siz /** @} */ +#if 0 /** * @defgroup apr_hash Hash Tables * @ingroup switch_apr @@ -184,6 +185,15 @@ SWITCH_DECLARE(switch_hash_index_t *) switch_hash_next(switch_hash_index_t * ht) */ SWITCH_DECLARE(void) switch_hash_this(switch_hash_index_t * hi, const void **key, switch_ssize_t *klen, void **val); + + +SWITCH_DECLARE(switch_memory_pool_t *) switch_hash_pool_get(switch_hash_t * ht); + +/** @} */ + + +#endif + /** * The default hash function. * @param key pointer to the key. @@ -192,9 +202,7 @@ SWITCH_DECLARE(void) switch_hash_this(switch_hash_index_t * hi, const void **key */ SWITCH_DECLARE(unsigned int) switch_hashfunc_default(const char *key, switch_ssize_t *klen); -SWITCH_DECLARE(switch_memory_pool_t *) switch_hash_pool_get(switch_hash_t * ht); -/** @} */ /** * @defgroup switch_time Time Routines * @ingroup switch_apr diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index 69dbdbc847..f9e0e23d60 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -203,15 +203,6 @@ SWITCH_DECLARE(char *) switch_channel_get_uuid(switch_channel_t *channel); */ SWITCH_DECLARE(switch_status_t) switch_channel_set_variable(switch_channel_t *channel, const char *varname, const char *value); -/*! - \brief Set a variable on a given channel, without duplicating the value from the session pool. - \param channel channel to set variable on - \param varname the name of the variable - \param value the vaule of the variable (MUST BE ALLOCATED FROM THE SESSION POOL ALREADY) - \returns SWITCH_STATUS_SUCCESS if successful -*/ -SWITCH_DECLARE(switch_status_t) switch_channel_set_variable_nodup(switch_channel_t *channel, const char *varname, char *value); - /*! \brief Retrieve a variable from a given channel \param channel channel to retrieve variable from @@ -227,7 +218,9 @@ SWITCH_DECLARE(char *) switch_channel_get_variable(switch_channel_t *channel, co * pool is NULL, then an internal, non-thread-safe iterator is used. * @remark Use switch_hash_next and switch_hash_this with this function to iterate all the channel variables */ -SWITCH_DECLARE(switch_hash_index_t *) switch_channel_variable_first(switch_channel_t *channel); +SWITCH_DECLARE(switch_event_header_t *) switch_channel_variable_first(switch_channel_t *channel); + + SWITCH_DECLARE(void) switch_channel_variable_last(switch_channel_t *channel); /*! diff --git a/src/include/switch_console.h b/src/include/switch_console.h index 156b9d83af..48b6499543 100644 --- a/src/include/switch_console.h +++ b/src/include/switch_console.h @@ -43,14 +43,15 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_CMD_CHUNK_LEN 1024 -#define SWITCH_STANDARD_STREAM(s) memset(&s, 0, sizeof(s)); if ((s.data = malloc(SWITCH_CMD_CHUNK_LEN))) { \ - memset(s.data, 0, SWITCH_CMD_CHUNK_LEN); \ - s.end = s.data;\ - s.data_size = SWITCH_CMD_CHUNK_LEN;\ - s.write_function = switch_console_stream_write;\ - s.alloc_len = SWITCH_CMD_CHUNK_LEN;\ - s.alloc_chunk = SWITCH_CMD_CHUNK_LEN;\ - } +#define SWITCH_STANDARD_STREAM(s) memset(&s, 0, sizeof(s)); s.data = malloc(SWITCH_CMD_CHUNK_LEN); \ + assert(s.data); \ + memset(s.data, 0, SWITCH_CMD_CHUNK_LEN); \ + s.end = s.data; \ + s.data_size = SWITCH_CMD_CHUNK_LEN; \ + s.write_function = switch_console_stream_write; \ + s.alloc_len = SWITCH_CMD_CHUNK_LEN; \ + s.alloc_chunk = SWITCH_CMD_CHUNK_LEN + /*! \brief A simple comand loop that reads input from the terminal */ diff --git a/src/include/switch_core.h b/src/include/switch_core.h index c977913f94..f08cafa4f8 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -230,18 +230,20 @@ SWITCH_DECLARE(void) switch_core_port_allocator_destroy(switch_core_port_allocat /*! \brief Initilize the core \param console optional FILE stream for output + \param flags core flags \param err a pointer to set any errors to \note to be called at application startup */ -SWITCH_DECLARE(switch_status_t) switch_core_init(const char *console, const char **err); +SWITCH_DECLARE(switch_status_t) switch_core_init(const char *console, switch_core_flag_t flags, const char **err); /*! \brief Initilize the core and load modules \param console optional FILE stream for output + \param flags core flags \param err a pointer to set any errors to \note to be called at application startup instead of switch_core_init. Includes module loading. */ -SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(const char *console, const char **err); +SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(const char *console, switch_core_flag_t flags, const char **err); /*! \brief Set/Get Session Limit @@ -326,6 +328,7 @@ SWITCH_DECLARE(int) switch_core_add_state_handler(const switch_state_handler_tab SWITCH_DECLARE(const switch_state_handler_table_t *) switch_core_get_state_handler(int index); ///\} +SWITCH_DECLARE(switch_status_t) switch_core_perform_new_memory_pool(switch_memory_pool_t **pool, const char *file, const char *func, int line); ///\defgroup memp Memory Pooling/Allocation ///\ingroup core1 @@ -334,13 +337,14 @@ SWITCH_DECLARE(const switch_state_handler_table_t *) switch_core_get_state_handl \brief Create a new sub memory pool from the core's master pool \return SWITCH_STATUS_SUCCESS on success */ -SWITCH_DECLARE(switch_status_t) switch_core_new_memory_pool(switch_memory_pool_t **pool); +#define switch_core_new_memory_pool(p) switch_core_perform_new_memory_pool(p, __FILE__, __SWITCH_FUNC__, __LINE__) +SWITCH_DECLARE(switch_status_t) switch_core_perform_destroy_memory_pool(switch_memory_pool_t **pool, const char *file, const char *func, int line); /*! \brief Returns a subpool back to the main pool \return SWITCH_STATUS_SUCCESS on success */ -SWITCH_DECLARE(switch_status_t) switch_core_destroy_memory_pool(switch_memory_pool_t **pool); +#define switch_core_destroy_memory_pool(p) switch_core_perform_destroy_memory_pool(p, __FILE__, __SWITCH_FUNC__, __LINE__) /*! \brief Start the session's state machine @@ -831,7 +835,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_init(switch_hash_t ** hash, swi \param hash the hash to destroy \return SWITCH_STATUS_SUCCESS if the hash is destroyed */ -SWITCH_DECLARE(switch_status_t) switch_core_hash_destroy(switch_hash_t * hash); +SWITCH_DECLARE(switch_status_t) switch_core_hash_destroy(switch_hash_t **hash); /*! \brief Insert data into a hash @@ -854,25 +858,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_insert(switch_hash_t * hash, co */ 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 - \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 - \return SWITCH_STATUS_SUCCESS if the data is added -*/ -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 \param hash the hash to delete from @@ -908,6 +893,10 @@ SWITCH_DECLARE(void *) switch_core_hash_find(switch_hash_t * hash, const char *k */ SWITCH_DECLARE(void *) switch_core_hash_find_locked(switch_hash_t * hash, const char *key, switch_mutex_t *mutex); +SWITCH_DECLARE(switch_hash_index_t *) switch_hash_first(char *depricate_me, switch_hash_t *hash); +SWITCH_DECLARE(switch_hash_index_t *) switch_hash_next(switch_hash_index_t *hi); +SWITCH_DECLARE(void) switch_hash_this(switch_hash_index_t *hi, const void **key, switch_ssize_t *klen, void **val); + ///\} ///\defgroup timer Timer Functions @@ -1393,6 +1382,12 @@ SWITCH_DECLARE(FILE *) switch_core_data_channel(switch_text_channel_t channel); */ SWITCH_DECLARE(switch_bool_t) switch_core_ready(void); +/*! + \brief return core flags + \return core flags +*/ +SWITCH_DECLARE(switch_core_flag_t) switch_core_flags(void); + /*! \brief Execute a management operation. \param relative_oid the relative oid of the operation. diff --git a/src/include/switch_event.h b/src/include/switch_event.h index 75658d74d9..44837e8ba0 100644 --- a/src/include/switch_event.h +++ b/src/include/switch_event.h @@ -174,6 +174,8 @@ SWITCH_DECLARE(char *) switch_event_get_body(switch_event_t *event); SWITCH_DECLARE(switch_status_t) switch_event_add_header(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *fmt, ...) PRINTF_FUNCTION(4, 5); +SWITCH_DECLARE(switch_status_t) switch_event_del_header(switch_event_t *event, const char *header_name); + /*! \brief Destroy an event \param event pointer to the pointer to event to destroy diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 21c332797d..051f746186 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -37,6 +37,7 @@ #include SWITCH_BEGIN_EXTERN_C +#define SWITCH_BLANK_STRING "" #define SWITCH_SEQ_ESC "\033[" /* Ansi Control character suffixes */ #define SWITCH_SEQ_HOME_CHAR 'H' @@ -123,8 +124,15 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_SPEECH_KEY "speech" #define SWITCH_UUID_BRIDGE "uuid_bridge" #define SWITCH_BITS_PER_BYTE 8 - typedef uint8_t switch_byte_t; +typedef uint8_t switch_byte_t; +typedef enum { + SCF_NONE = 0, + SCF_USE_SQL = ( 1 << 0), + SCF_NO_NEW_SESSIONS = (1 << 1), + SCF_SHUTTING_DOWN = (1 << 2), + SCF_CRASH_PROT = (1 << 3) +} switch_core_flag_t; typedef enum { SWITCH_ENDPOINT_INTERFACE, @@ -1087,6 +1095,10 @@ 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); +typedef struct switch_hash switch_hash_t; +struct HashElem; +typedef struct HashElem switch_hash_index_t; + #define SWITCH_API_VERSION 1 #define SWITCH_MODULE_LOAD_ARGS (switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 509f61a204..9a2aa9c769 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -104,16 +104,16 @@ SWITCH_STANDARD_API(ctl_function) if ((mydata = strdup(cmd))) { argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - if (!strcmp(argv[0], "hupall")) { + if (!strcasecmp(argv[0], "hupall")) { arg = 1; switch_core_session_ctl(SCSC_HUPALL, &arg); - } else if (!strcmp(argv[0], "pause")) { + } else if (!strcasecmp(argv[0], "pause")) { arg = 1; switch_core_session_ctl(SCSC_PAUSE_INBOUND, &arg); - } else if (!strcmp(argv[0], "resume")) { + } else if (!strcasecmp(argv[0], "resume")) { arg = 0; switch_core_session_ctl(SCSC_PAUSE_INBOUND, &arg); - } else if (!strcmp(argv[0], "shutdown")) { + } else if (!strcasecmp(argv[0], "shutdown")) { arg = 0; switch_core_session_ctl(SCSC_SHUTDOWN, &arg); } else { @@ -431,7 +431,7 @@ SWITCH_STANDARD_API(uuid_media_function) if (switch_strlen_zero(cmd) || argc < 1) { stream->write_function(stream, "USAGE: %s\n", MEDIA_SYNTAX); } else { - if (!strcmp(argv[0], "off")) { + if (!strcasecmp(argv[0], "off")) { status = switch_ivr_nomedia(argv[1], SMF_REBRIDGE); } else { status = switch_ivr_media(argv[0], SMF_REBRIDGE); @@ -469,11 +469,11 @@ SWITCH_STANDARD_API(uuid_broadcast_function) switch_media_flag_t flags = SMF_NONE; if (argv[2]) { - if (!strcmp(argv[2], "both")) { + if (!strcasecmp(argv[2], "both")) { flags |= (SMF_ECHO_ALEG | SMF_ECHO_BLEG); - } else if (!strcmp(argv[2], "aleg")) { + } else if (!strcasecmp(argv[2], "aleg")) { flags |= SMF_ECHO_ALEG; - } else if (!strcmp(argv[2], "bleg")) { + } else if (!strcasecmp(argv[2], "bleg")) { flags |= SMF_ECHO_BLEG; } } else { @@ -516,11 +516,11 @@ SWITCH_STANDARD_API(sched_broadcast_function) } if (argv[3]) { - if (!strcmp(argv[3], "both")) { + if (!strcasecmp(argv[3], "both")) { flags |= (SMF_ECHO_ALEG | SMF_ECHO_BLEG); - } else if (!strcmp(argv[3], "aleg")) { + } else if (!strcasecmp(argv[3], "aleg")) { flags |= SMF_ECHO_ALEG; - } else if (!strcmp(argv[3], "bleg")) { + } else if (!strcasecmp(argv[3], "bleg")) { flags |= SMF_ECHO_BLEG; } } else { @@ -553,7 +553,7 @@ SWITCH_STANDARD_API(uuid_hold_function) if (switch_strlen_zero(cmd) || argc < 1) { stream->write_function(stream, "USAGE: %s\n", HOLD_SYNTAX); } else { - if (!strcmp(argv[0], "off")) { + if (!strcasecmp(argv[0], "off")) { status = switch_ivr_unhold_uuid(argv[1]); } else { status = switch_ivr_hold_uuid(argv[0]); @@ -799,27 +799,28 @@ SWITCH_STANDARD_API(originate_function) { switch_channel_t *caller_channel; switch_core_session_t *caller_session = NULL; - char *mycmd = NULL, *argv[7] = { 0 }; + char *mycmd = NULL, *argv[10] = { 0 }; int i = 0, x, argc = 0; char *aleg, *exten, *dp, *context, *cid_name, *cid_num; uint32_t timeout = 60; switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING; uint8_t machine = 1; - - if (session) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (session || switch_strlen_zero(cmd)) { stream->write_function(stream, "Illegal Usage\n"); return SWITCH_STATUS_SUCCESS; } - if (!switch_strlen_zero(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (switch_strlen_zero(cmd) || argc < 2 || argc > 7) { + mycmd = strdup(cmd); + assert(mycmd); + argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + + if (argc < 2 || argc > 7) { stream->write_function(stream, "USAGE: %s\n", ORIGINATE_SYNTAX); - switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; + goto done; } + for (x = 0; x < argc; x++) { if (!strcasecmp(argv[x], "undef")) { @@ -857,14 +858,13 @@ SWITCH_STANDARD_API(originate_function) } else { stream->write_function(stream, "Cannot Create Outgoing Channel! [%s] cause: %s\n", aleg, switch_channel_cause2str(cause)); } - switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; + goto done; } caller_channel = switch_core_session_get_channel(caller_session); assert(caller_channel != NULL); switch_channel_clear_state_handler(caller_channel, NULL); - + if (*exten == '&' && *(exten + 1)) { switch_caller_extension_t *extension = NULL; char *app_name = switch_core_session_strdup(caller_session, (exten + 1)); @@ -880,9 +880,7 @@ SWITCH_STANDARD_API(originate_function) if ((extension = switch_caller_extension_new(caller_session, app_name, arg)) == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "memory error!\n"); - switch_channel_hangup(caller_channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - switch_safe_free(mycmd); - return SWITCH_STATUS_MEMERR; + abort(); } switch_caller_extension_add_application(caller_session, extension, app_name, arg); switch_channel_set_caller_extension(caller_channel, extension); @@ -901,8 +899,9 @@ SWITCH_STANDARD_API(originate_function) switch_core_session_rwunlock(caller_session); } + done: switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; + return status; } static void sch_api_callback(switch_scheduler_task_t *task) @@ -1140,6 +1139,7 @@ SWITCH_STANDARD_API(show_function) char *mydata = NULL, *argv[6] = {0}; int argc; char *command = NULL, *as = NULL; + switch_core_flag_t cflags = switch_core_flags(); if (session) { return SWITCH_STATUS_FALSE; @@ -1159,20 +1159,25 @@ SWITCH_STANDARD_API(show_function) holder.print_title = 1; + if (!(cflags & SCF_USE_SQL) && !strcasecmp(command, "channels")) { + stream->write_function(stream, "SQL DISABLED NO CHANNEL DATA AVAILABLE!\n"); + return SWITCH_STATUS_SUCCESS; + } + // If you changes the field qty or order of any of these select // statmements, you must also change show_callback and friends to match! if (!command) { stream->write_function(stream, "USAGE: %s\n", SHOW_SYNTAX); return SWITCH_STATUS_SUCCESS; - } else if (!strcmp(command, "codec") || !strcmp(command, "dialplan") || !strcmp(command, "file") || !strcmp(command, "timer")) { + } else if (!strcasecmp(command, "codec") || !strcasecmp(command, "dialplan") || !strcasecmp(command, "file") || !strcasecmp(command, "timer")) { sprintf(sql, "select type, name from interfaces where type = '%s'", command); - } else if (!strcmp(command, "tasks")) { + } else if (!strcasecmp(command, "tasks")) { sprintf(sql, "select * from %s", command); - } else if (!strcmp(command, "application") || !strcmp(command, "api")) { + } else if (!strcasecmp(command, "application") || !strcasecmp(command, "api")) { sprintf(sql, "select name, description, syntax from interfaces where type = '%s' and description != ''", command); - } else if (!strcmp(command, "calls")) { + } else if (!strcasecmp(command, "calls")) { sprintf(sql, "select * from calls"); - } else if (!strcmp(command, "channels")) { + } else if (!strcasecmp(command, "channels")) { sprintf(sql, "select * from channels"); } else if (!strncasecmp(command, "help", 4)) { char *cmdname = NULL; diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index f5a78ecaa9..2259aa7f4f 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -5038,6 +5038,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_conference_shutdown) /* free api interface help ".syntax" field string */ switch_safe_free(api_syntax); } + switch_core_hash_destroy(&globals.conference_hash); return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/applications/mod_enum/mod_enum.c b/src/mod/applications/mod_enum/mod_enum.c index b03783a9a9..e888c401b8 100644 --- a/src/mod/applications/mod_enum/mod_enum.c +++ b/src/mod/applications/mod_enum/mod_enum.c @@ -37,7 +37,8 @@ #endif SWITCH_MODULE_LOAD_FUNCTION(mod_enum_load); -SWITCH_MODULE_DEFINITION(mod_enum, mod_enum_load, NULL, NULL); +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_enum_shutdown); +SWITCH_MODULE_DEFINITION(mod_enum, mod_enum_load, mod_enum_shutdown, NULL); struct enum_record { int order; @@ -582,13 +583,10 @@ SWITCH_STANDARD_APP(enum_app_function) dest = argv[0]; root = argv[1] ? argv[1] : globals.root; if (enum_lookup(root, data, &results) == SWITCH_STATUS_SUCCESS) { - switch_hash_index_t *hi; - void *vval; - const void *vvar; - + switch_event_header_t *hi; if ((hi = switch_channel_variable_first(channel))) { - for (; hi; hi = switch_hash_next(hi)) { - switch_hash_this(hi, &vvar, NULL, &vval); + for (; hi; hi = hi->next) { + char *vvar = hi->name; if (vvar && !strncmp(vvar, "enum_", 5)) { switch_channel_set_variable(channel, (char *) vvar, NULL); } @@ -702,3 +700,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_enum_load) /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; } + +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_enum_shutdown) +{ + switch_core_hash_destroy(&globals.routes); + return SWITCH_STATUS_SUCCESS; +} diff --git a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c index f2a957afe0..3884f403f5 100644 --- a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c +++ b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c @@ -197,7 +197,7 @@ static switch_status_t dialplan_xml_locate(switch_core_session_t *session, switc char *encode_buf = NULL; char *prof[12] = { 0 }, *prof_names[12] = { 0}, *e = NULL; - switch_hash_index_t *hi; + switch_event_header_t *hi; uint32_t x = 0; channel = switch_core_session_get_channel(session); @@ -253,10 +253,9 @@ static switch_status_t dialplan_xml_locate(switch_core_session_t *session, switc } if ((hi = switch_channel_variable_first(channel))) { - for (; hi; hi = switch_hash_next(hi)) { - void *val; - const void *var; - switch_hash_this(hi, &var, NULL, &val); + for (; hi; hi = hi->next) { + char *var = hi->name; + char *val = hi->value; new_len = (strlen((char *) var) * 3) + 1; if (encode_len < new_len) { diff --git a/src/mod/endpoints/mod_alsa/mod_alsa.c b/src/mod/endpoints/mod_alsa/mod_alsa.c index 1ad2611d71..3d77e99310 100644 --- a/src/mod/endpoints/mod_alsa/mod_alsa.c +++ b/src/mod/endpoints/mod_alsa/mod_alsa.c @@ -956,6 +956,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_alsa_shutdown) if (globals.write_codec.implementation) { switch_core_codec_destroy(&globals.write_codec); } + switch_core_hash_destroy(&globals.call_hash); return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 7ecb7f868b..c3e1f2c383 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -1905,6 +1905,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_dingaling_shutdown) ldl_global_destroy(); } } + switch_core_hash_destroy(&globals.profile_hash); return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/endpoints/mod_portaudio/mod_portaudio.c b/src/mod/endpoints/mod_portaudio/mod_portaudio.c index a6e7ede7c6..c8b0bfeb2f 100644 --- a/src/mod/endpoints/mod_portaudio/mod_portaudio.c +++ b/src/mod/endpoints/mod_portaudio/mod_portaudio.c @@ -973,6 +973,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_shutdown) switch_core_timer_destroy(&globals.timer); Pa_Terminate(); + switch_core_hash_destroy(&globals.call_hash); return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 09b061db90..092b37451e 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1360,6 +1360,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session if (!(tech_pvt = (struct private_object *) switch_core_session_alloc(nsession, sizeof(*tech_pvt)))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Creating Session\n"); switch_core_session_destroy(&nsession); + *pool = NULL; goto done; } switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(nsession)); @@ -1375,6 +1376,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid URL\n"); switch_core_session_destroy(&nsession); cause = SWITCH_CAUSE_INVALID_NUMBER_FORMAT; + *pool = NULL; goto done; } @@ -1384,6 +1386,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid URL\n"); switch_core_session_destroy(&nsession); cause = SWITCH_CAUSE_INVALID_NUMBER_FORMAT; + *pool = NULL; goto done; } @@ -1393,6 +1396,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Gateway\n"); switch_core_session_destroy(&nsession); cause = SWITCH_CAUSE_INVALID_NUMBER_FORMAT; + *pool = NULL; goto done; } @@ -1411,6 +1415,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid URL\n"); switch_core_session_destroy(&nsession); cause = SWITCH_CAUSE_INVALID_NUMBER_FORMAT; + *pool = NULL; goto done; } *dest++ = '\0'; @@ -1419,6 +1424,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile\n"); switch_core_session_destroy(&nsession); cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; + *pool = NULL; goto done; } @@ -1440,6 +1446,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate registered user %s@%s\n", dest, host); cause = SWITCH_CAUSE_NO_ROUTE_DESTINATION; switch_core_session_destroy(&nsession); + *pool = NULL; goto done; } } else if (!strchr(dest, '@')) { @@ -1452,6 +1459,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate registered user %s@%s\n", dest, profile_name); cause = SWITCH_CAUSE_NO_ROUTE_DESTINATION; switch_core_session_destroy(&nsession); + *pool = NULL; goto done; } } else { @@ -1609,6 +1617,9 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown) su_deinit(); + switch_core_hash_destroy(&mod_sofia_globals.profile_hash); + switch_core_hash_destroy(&mod_sofia_globals.gateway_hash); + return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index b52dede84e..b0d21eee65 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -83,7 +83,6 @@ typedef struct private_object private_object_t; struct sofia_private { char uuid[SWITCH_UUID_FORMATTED_LENGTH + 1]; sofia_gateway_t *gateway; - su_home_t *home; }; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 5b813f805c..0f891317ea 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -419,6 +419,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void sofia_glue_del_profile(profile); + switch_core_hash_destroy(&profile->chat_hash); switch_thread_rwlock_unlock(profile->rwlock); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write unlock %s\n", profile->name); @@ -1146,38 +1147,46 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (match) { nua_handle_t *bnh; sip_replaces_t *replaces; + su_home_t *home = NULL; switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED"); switch_set_flag_locked(tech_pvt, TFLAG_READY); switch_channel_set_state(channel, CS_INIT); //switch_core_session_thread_launch(session); - if (replaces_str && (replaces = sip_replaces_make(tech_pvt->sofia_private->home, replaces_str)) - && (bnh = nua_handle_by_replaces(nua, replaces))) { - sofia_private_t *b_private; + if (replaces_str) { + home = su_home_new(sizeof(*home)); + assert(home != NULL); + if ((replaces = sip_replaces_make(home, replaces_str)) + && (bnh = nua_handle_by_replaces(nua, replaces))) { + sofia_private_t *b_private; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Processing Replaces Attended Transfer\n"); - while (switch_channel_get_state(channel) < CS_EXECUTE) { - switch_yield(10000); - } - - if ((b_private = nua_handle_magic(bnh))) { - char *br_b = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE); - char *br_a = b_private->uuid; - - if (br_b) { - switch_ivr_uuid_bridge(br_a, br_b); - switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER"); - switch_channel_hangup(channel, SWITCH_CAUSE_ATTENDED_TRANSFER); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Processing Replaces Attended Transfer\n"); + while (switch_channel_get_state(channel) < CS_EXECUTE) { + switch_yield(10000); + } + + if ((b_private = nua_handle_magic(bnh))) { + char *br_b = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE); + char *br_a = b_private->uuid; + + if (br_b) { + switch_ivr_uuid_bridge(br_a, br_b); + switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER"); + switch_channel_hangup(channel, SWITCH_CAUSE_ATTENDED_TRANSFER); + } else { + switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER_ERROR"); + switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); + } } else { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER_ERROR"); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); } - } else { - switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER_ERROR"); - switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); + nua_handle_unref(bnh); } - nua_handle_unref(bnh); + su_home_unref(home); + home = NULL; } + goto done; } @@ -1351,9 +1360,6 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } if (tech_pvt->sofia_private) { - if (tech_pvt->sofia_private->home) { - su_home_unref(tech_pvt->sofia_private->home); - } free(tech_pvt->sofia_private); tech_pvt->sofia_private = NULL; } @@ -1362,9 +1368,6 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } else if (sofia_private) { - if (sofia_private->home) { - su_home_unref(sofia_private->home); - } free(sofia_private); } @@ -1391,6 +1394,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t private_object_t *tech_pvt = NULL; char *etmp = NULL, *exten = NULL; switch_channel_t *channel_a = NULL, *channel_b = NULL; + su_home_t *home = NULL; tech_pvt = switch_core_session_get_private(session); channel_a = switch_core_session_get_channel(session); @@ -1427,10 +1431,9 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t if ((rep = strchr(refer_to->r_url->url_headers, '='))) { char *br_a = NULL, *br_b = NULL; char *buf; + rep++; - - if ((buf = switch_core_session_alloc(session, strlen(rep) + 1))) { rep = url_unescape(buf, (const char *) rep); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Replaces: [%s]\n", rep); @@ -1438,7 +1441,11 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n"); goto done; } - if ((replaces = sip_replaces_make(tech_pvt->sofia_private->home, rep)) + + home = su_home_new(sizeof(*home)); + assert(home != NULL); + + if ((replaces = sip_replaces_make(home, rep)) && (bnh = nua_handle_by_replaces(nua, replaces))) { sofia_private_t *b_private = NULL; private_object_t *b_tech_pvt = NULL; @@ -1612,6 +1619,11 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t } done: + if (home) { + su_home_unref(home); + home = NULL; + } + if (exten && strchr(exten, '@')) { switch_safe_free(exten); } @@ -1704,7 +1716,7 @@ const char *_url_set_chanvars(switch_core_session_t *session, url_t *url, const } else { uri = switch_core_session_sprintf(session, "%s:%s", host, port); } - switch_channel_set_variable_nodup(channel, uri_var, uri); + switch_channel_set_variable(channel, uri_var, uri); switch_channel_set_variable(channel, host_var, host); } @@ -2024,8 +2036,10 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ abort(); } memset(tech_pvt->sofia_private, 0, sizeof(*tech_pvt->sofia_private)); - tech_pvt->sofia_private->home = su_home_new(sizeof(*tech_pvt->sofia_private->home)); - sofia_presence_set_chat_hash(tech_pvt, sip); + + if ((profile->pflags & PFLAG_PRESENCE)) { + sofia_presence_set_chat_hash(tech_pvt, sip); + } switch_copy_string(tech_pvt->sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(tech_pvt->sofia_private->uuid)); nua_handle_bind(nh, tech_pvt->sofia_private); tech_pvt->nh = nh; diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 117743ad44..133d0827ad 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -441,10 +441,8 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) char *e_dest = NULL; const char *holdstr = ""; switch_stream_handle_t stream = { 0 }; - switch_hash_index_t *hi; - void *vval; + switch_event_header_t *hi; char *extra_headers = NULL; - const void *vvar; switch_status_t status = SWITCH_STATUS_FALSE; char *rep; @@ -541,7 +539,6 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) } memset(tech_pvt->sofia_private, 0, sizeof(*tech_pvt->sofia_private)); - tech_pvt->sofia_private->home = su_home_new(sizeof(*tech_pvt->sofia_private->home)); switch_copy_string(tech_pvt->sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(tech_pvt->sofia_private->uuid)); nua_handle_bind(tech_pvt->nh, tech_pvt->sofia_private); @@ -575,17 +572,15 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) SWITCH_STANDARD_STREAM(stream); if ((hi = switch_channel_variable_first(channel))) { - for (; hi; hi = switch_hash_next(hi)) { - switch_hash_this(hi, &vvar, NULL, &vval); - if (vvar && vval) { - const char *name = vvar; - char *value = (char *) vval; - - if (!strncasecmp(name, SOFIA_SIP_HEADER_PREFIX, strlen(SOFIA_SIP_HEADER_PREFIX))) { - const char *hname = name + strlen(SOFIA_SIP_HEADER_PREFIX); - stream.write_function(&stream, "%s: %s\r\n", hname, value); - } + for (; hi; hi = hi = hi->next) { + const char *name = (char *) hi->name; + char *value = (char *) hi->value; + + if (!strncasecmp(name, SOFIA_SIP_HEADER_PREFIX, strlen(SOFIA_SIP_HEADER_PREFIX))) { + const char *hname = name + strlen(SOFIA_SIP_HEADER_PREFIX); + stream.write_function(&stream, "%s: %s\r\n", hname, value); } + } switch_channel_variable_last(channel); } @@ -1532,31 +1527,14 @@ switch_status_t sofia_glue_add_profile(char *key, sofia_profile_t *profile) void sofia_glue_del_profile(sofia_profile_t *profile) { - switch_hash_index_t *hi; - void *vval; - const void *vvar; - sofia_profile_t *this_profile; - sofia_gateway_t *gp, *this_gateway; - + sofia_gateway_t *gp; switch_mutex_lock(mod_sofia_globals.hash_mutex); - for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) { - switch_hash_this(hi, &vvar, NULL, &vval); - this_profile = (sofia_profile_t *) vval; - if (this_profile == profile) { - switch_core_hash_delete(mod_sofia_globals.profile_hash, vvar); - } + switch_core_hash_delete(mod_sofia_globals.profile_hash, profile->name); + for (gp = profile->gateways; gp; gp = gp->next) { + switch_core_hash_delete(mod_sofia_globals.gateway_hash, gp->name); } - for (hi = switch_hash_first(NULL, mod_sofia_globals.gateway_hash); hi; hi = switch_hash_next(hi)) { - switch_hash_this(hi, &vvar, NULL, &vval); - this_gateway = (sofia_gateway_t *) vval; - for (gp = profile->gateways; gp; gp = gp->next) { - if (gp == this_gateway) { - switch_core_hash_delete(mod_sofia_globals.gateway_hash, vvar); - } - } - } switch_mutex_unlock(mod_sofia_globals.hash_mutex); } diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index f0691cca15..d0eb637434 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -1051,15 +1051,20 @@ void sofia_presence_set_chat_hash(private_object_t *tech_pvt, sip_t const *sip) { char hash_key[256] = ""; char buf[512]; + su_home_t *home = NULL; if (tech_pvt->hash_key || !sip || !sip->sip_from || !sip->sip_from->a_url || !sip->sip_from->a_url->url_user || !sip->sip_from->a_url->url_host) { return; } if (sofia_reg_find_reg_url(tech_pvt->profile, sip->sip_from->a_url->url_user, sip->sip_from->a_url->url_host, buf, sizeof(buf))) { - tech_pvt->chat_from = sip_header_as_string(tech_pvt->sofia_private->home, (const sip_header_t *) sip->sip_to); + home = su_home_new(sizeof(*home)); + assert(home != NULL); + tech_pvt->chat_from = sip_header_as_string(home, (const sip_header_t *) sip->sip_to); tech_pvt->chat_to = switch_core_session_strdup(tech_pvt->session, buf); sofia_presence_set_hash_key(hash_key, sizeof(hash_key), sip); + su_home_unref(home); + home = NULL; } else { return; } diff --git a/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c b/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c index fa37f18884..8d638ac914 100644 --- a/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c +++ b/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c @@ -41,8 +41,9 @@ #endif //#define DOTRACE +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_wanpipe_shutdown) SWITCH_MODULE_LOAD_FUNCTION(mod_wanpipe_load); -SWITCH_MODULE_DEFINITION(mod_wanpipe, mod_wanpipe_load, NULL, NULL); +SWITCH_MODULE_DEFINITION(mod_wanpipe, mod_wanpipe_load, mod_wanpipe_shutdown, NULL); #define STRLEN 15 @@ -1360,6 +1361,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_wanpipe_load) return status; } +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_wanpipe_shutdown) +{ + switch_core_hash_destroy(&globals.call_hash); + return SWITCH_STATUS_SUCCESS; +} + /*event Handlers */ static int on_info(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *pevent) diff --git a/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c b/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c index da85092f19..b05239539d 100644 --- a/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c +++ b/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c @@ -244,6 +244,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_event_multicast_shutdown) x++; switch_yield(1000); } + switch_core_hash_destroy(&globals.event_hash); return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c index c42572208a..96ed79b198 100644 --- a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c +++ b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c @@ -510,6 +510,7 @@ struct api_command_struct { listener_t *listener; char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; uint8_t bg; + switch_memory_pool_t *pool; }; static void *SWITCH_THREAD_FUNC api_exec(switch_thread_t * thread, void *obj) @@ -520,7 +521,7 @@ static void *SWITCH_THREAD_FUNC api_exec(switch_thread_t * thread, void *obj) char *reply, *freply = NULL; switch_status_t status; - if (switch_thread_rwlock_tryrdlock(acs->listener->rwlock) != SWITCH_STATUS_SUCCESS) { + if (!acs->listener || !acs->listener->rwlock || switch_thread_rwlock_tryrdlock(acs->listener->rwlock) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error! cannot get read lock.\n"); goto done; } @@ -560,18 +561,16 @@ static void *SWITCH_THREAD_FUNC api_exec(switch_thread_t * thread, void *obj) switch_safe_free(stream.data); switch_safe_free(freply); - switch_thread_rwlock_unlock(acs->listener->rwlock); - + if (acs->listener->rwlock) { + switch_thread_rwlock_unlock(acs->listener->rwlock); + } done: if (acs && acs->bg) { - if (acs->api_cmd) { - free(acs->api_cmd); - } - if (acs->arg) { - free(acs->arg); - } - free(acs); + switch_memory_pool_t *pool = acs->pool; + acs = NULL; + switch_core_destroy_memory_pool(&pool); + pool = NULL; } return NULL; @@ -758,45 +757,45 @@ static switch_status_t parse_command(listener_t * listener, switch_event_t *even return SWITCH_STATUS_SUCCESS; } else if (!strncasecmp(cmd, "bgapi ", 6)) { - struct api_command_struct *acs; + struct api_command_struct *acs = NULL; char *api_cmd = cmd + 6; char *arg = NULL; char *uuid_str = NULL; + switch_memory_pool_t *pool; + switch_thread_t *thread; + switch_threadattr_t *thd_attr = NULL; + switch_uuid_t uuid; + strip_cr(api_cmd); if ((arg = strchr(api_cmd, ' '))) { *arg++ = '\0'; } - if ((acs = malloc(sizeof(*acs)))) { - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - switch_uuid_t uuid; - - memset(acs, 0, sizeof(*acs)); - acs->listener = listener; - if (api_cmd) { - acs->api_cmd = strdup(api_cmd); - } - if (arg) { - acs->arg = strdup(arg); - } - acs->bg = 1; - switch_threadattr_create(&thd_attr, listener->pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, api_exec, acs, listener->pool); - if ((uuid_str = switch_event_get_header(event, "job-uuid"))) { - switch_copy_string(acs->uuid_str, uuid_str, sizeof(acs->uuid_str)); - } else { - switch_uuid_get(&uuid); - switch_uuid_format(acs->uuid_str, &uuid); - } - snprintf(reply, reply_len, "+OK Job-UUID: %s", acs->uuid_str); - } else { - snprintf(reply, reply_len, "-ERR memory error!"); + switch_core_new_memory_pool(&pool); + acs = switch_core_alloc(pool, sizeof(*acs)); + assert(acs); + acs->pool = pool; + acs->listener = listener; + if (api_cmd) { + acs->api_cmd = switch_core_strdup(acs->pool, api_cmd); } - + if (arg) { + acs->arg = switch_core_strdup(acs->pool, arg); + } + acs->bg = 1; + switch_threadattr_create(&thd_attr, acs->pool); + switch_threadattr_detach_set(thd_attr, 1); + switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_thread_create(&thread, thd_attr, api_exec, acs, acs->pool); + if ((uuid_str = switch_event_get_header(event, "job-uuid"))) { + switch_copy_string(acs->uuid_str, uuid_str, sizeof(acs->uuid_str)); + } else { + switch_uuid_get(&uuid); + switch_uuid_format(acs->uuid_str, &uuid); + } + snprintf(reply, reply_len, "+OK Job-UUID: %s", acs->uuid_str); + return SWITCH_STATUS_SUCCESS; } else if (!strncasecmp(cmd, "log", 3)) { @@ -861,7 +860,7 @@ static switch_status_t parse_command(listener_t * listener, switch_event_t *even } if (custom) { - switch_core_hash_insert_dup(listener->event_hash, cur, MARKER); + switch_core_hash_insert(listener->event_hash, cur, MARKER); } else if (switch_name_event(cur, &type) == SWITCH_STATUS_SUCCESS) { key_count++; if (type == SWITCH_EVENT_ALL) { @@ -957,6 +956,7 @@ static switch_status_t parse_command(listener_t * listener, switch_event_t *even listener->event_list[x] = 0; } /* wipe the hash */ + switch_core_hash_destroy(&listener->event_hash); switch_core_hash_init(&listener->event_hash, listener->pool); snprintf(reply, reply_len, "+OK no longer listening for events"); } else { @@ -1105,14 +1105,15 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t * thread, void *obj done: remove_listener(listener); - close_socket(&listener->sock); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Session complete, waiting for children\n"); switch_thread_rwlock_wrlock(listener->rwlock); switch_thread_rwlock_unlock(listener->rwlock); + close_socket(&listener->sock); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connection Closed\n"); + switch_core_hash_destroy(&listener->event_hash); if (session) { switch_channel_clear_flag(switch_core_session_get_channel(session), CF_CONTROLLED); diff --git a/src/mod/formats/mod_local_stream/mod_local_stream.c b/src/mod/formats/mod_local_stream/mod_local_stream.c index fa3db3c965..f880aa4c93 100644 --- a/src/mod/formats/mod_local_stream/mod_local_stream.c +++ b/src/mod/formats/mod_local_stream/mod_local_stream.c @@ -365,6 +365,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_local_stream_shutdown) { RUNNING = 0; switch_yield(500000); + switch_core_hash_destroy(&globals.source_hash); return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/formats/mod_sndfile/mod_sndfile.c b/src/mod/formats/mod_sndfile/mod_sndfile.c index 79094dbeda..b04764fb7f 100644 --- a/src/mod/formats/mod_sndfile/mod_sndfile.c +++ b/src/mod/formats/mod_sndfile/mod_sndfile.c @@ -33,7 +33,8 @@ #include SWITCH_MODULE_LOAD_FUNCTION(mod_sndfile_load); -SWITCH_MODULE_DEFINITION(mod_sndfile, mod_sndfile_load, NULL, NULL); +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sndfile_shutdown); +SWITCH_MODULE_DEFINITION(mod_sndfile, mod_sndfile_load, mod_sndfile_shutdown, NULL); static switch_memory_pool_t *module_pool = NULL; @@ -370,6 +371,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sndfile_load) return SWITCH_STATUS_SUCCESS; } +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sndfile_shutdown) +{ + switch_core_hash_destroy(&globals.format_hash); + return SWITCH_STATUS_SUCCESS; +} + /* For Emacs: * Local Variables: * mode:c diff --git a/src/mod/languages/mod_mono/mod_mono.c b/src/mod/languages/mod_mono/mod_mono.c index 0468d074c5..ea2c232d76 100644 --- a/src/mod/languages/mod_mono/mod_mono.c +++ b/src/mod/languages/mod_mono/mod_mono.c @@ -168,6 +168,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mono_shutdown) globals.domain = NULL; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Deallocated mono runtime.\n"); } + switch_core_hash_destroy(&globals.plugins); return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c index 4e706012df..dab916e14d 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c @@ -3293,6 +3293,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_spidermonkey_load) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_spidermonkey_shutdown) { curl_global_cleanup(); + switch_core_hash_destroy(&module_manager.mod_hash); + switch_core_hash_destroy(&module_manager.load_hash); return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/loggers/mod_console/mod_console.c b/src/mod/loggers/mod_console/mod_console.c index 0af0157315..891bb098a9 100644 --- a/src/mod/loggers/mod_console/mod_console.c +++ b/src/mod/loggers/mod_console/mod_console.c @@ -32,9 +32,12 @@ #include SWITCH_MODULE_LOAD_FUNCTION(mod_console_load); -SWITCH_MODULE_DEFINITION(mod_console, mod_console_load, NULL, NULL); +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_console_shutdown); +SWITCH_MODULE_DEFINITION(mod_console, mod_console_load, mod_console_shutdown, NULL); static const uint8_t STATIC_LEVELS[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; +static int RUNNING = 0; + static int COLORIZE = 0; #ifdef WIN32 static HANDLE hStdout; @@ -98,6 +101,12 @@ static switch_status_t config_logger(void) return SWITCH_STATUS_TERM; } + if (log_hash) { + switch_core_hash_destroy(&log_hash); + } + if (name_hash) { + switch_core_hash_destroy(&name_hash); + } switch_core_hash_init(&log_hash, module_pool); switch_core_hash_init(&name_hash, module_pool); @@ -137,7 +146,11 @@ static switch_status_t config_logger(void) static switch_status_t switch_console_logger(const switch_log_node_t *node, switch_log_level_t level) { FILE *handle; - + /* + if (!RUNNING) { + return SWITCH_STATUS_FALSE; + } + */ if ((handle = switch_core_data_channel(SWITCH_CHANNEL_ID_LOG))) { uint8_t *lookup = NULL; switch_log_level_t level = SWITCH_LOG_DEBUG; @@ -188,11 +201,19 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_console_load) switch_log_bind_logger(switch_console_logger, SWITCH_LOG_DEBUG); config_logger(); - + RUNNING = 1; /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; } +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_console_shutdown) +{ + //switch_core_hash_destroy(&log_hash); + //switch_core_hash_destroy(&name_hash); + RUNNING = 0; + return SWITCH_STATUS_SUCCESS; +} + /* For Emacs: * Local Variables: * mode:c diff --git a/src/switch.c b/src/switch.c index cc083d06a2..7a8b43bbaa 100644 --- a/src/switch.c +++ b/src/switch.c @@ -213,6 +213,7 @@ int main(int argc, char *argv[]) char *usageDesc; int alt_dirs = 0; int known_opt; + switch_core_flag_t flags = SCF_USE_SQL; #ifdef WIN32 SERVICE_TABLE_ENTRY dispatchTable[] = { @@ -224,6 +225,7 @@ int main(int argc, char *argv[]) "\t-install -- install freeswitch as a service\n" "\t-uninstall -- remove freeswitch as a service\n" "\t-hp -- enable high priority settings\n" + "\t-nosql -- disable internal sql scoreboard\n" "\t-stop -- stop freeswitch\n" "\t-nc -- do not output to a console and background\n" "\t-conf [confdir] -- specify an alternate config dir\n" @@ -233,6 +235,7 @@ int main(int argc, char *argv[]) "\t-help -- this message\n" "\t-nf -- no forking\n" "\t-hp -- enable high priority settings\n" + "\t-nosql -- disable internal sql scoreboard\n" "\t-stop -- stop freeswitch\n" "\t-nc -- do not output to a console and background\n" "\t-conf [confdir] -- specify an alternate config dir\n" @@ -291,6 +294,11 @@ int main(int argc, char *argv[]) known_opt++; } + if (argv[x] && !strcmp(argv[x], "-nosql")) { + flags &= ~SCF_USE_SQL; + known_opt++; + } + if (argv[x] && !strcmp(argv[x], "-stop")) { die++; known_opt++; @@ -372,7 +380,7 @@ int main(int argc, char *argv[]) #endif } - if (switch_core_init_and_modload(nc ? lfile : NULL, &err) != SWITCH_STATUS_SUCCESS) { + if (switch_core_init_and_modload(nc ? lfile : NULL, flags, &err) != SWITCH_STATUS_SUCCESS) { fprintf(stderr, "Cannot Initilize [%s]\n", err); return 255; } diff --git a/src/switch_apr.c b/src/switch_apr.c index b02680471b..52a0fc8796 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -73,6 +73,7 @@ SWITCH_DECLARE(void) switch_pool_clear(switch_memory_pool_t *p) apr_pool_clear(p); } +#if 0 /* Hash tables */ SWITCH_DECLARE(switch_hash_index_t *) switch_hash_first(switch_memory_pool_t *p, switch_hash_t * ht) @@ -87,18 +88,27 @@ SWITCH_DECLARE(switch_hash_index_t *) switch_hash_next(switch_hash_index_t * ht) SWITCH_DECLARE(void) switch_hash_this(switch_hash_index_t * hi, const void **key, switch_ssize_t *klen, void **val) { + if (key) { + *key = NULL; + } + if (val) { + *val = NULL; + } apr_hash_this(hi, key, klen, val); } + +SWITCH_DECLARE(switch_memory_pool_t *) switch_hash_pool_get(switch_hash_t * ht) +{ + return apr_hash_pool_get(ht); +} +#endif + SWITCH_DECLARE(unsigned int) switch_hashfunc_default(const char *key, switch_ssize_t *klen) { return apr_hashfunc_default(key, klen); } -SWITCH_DECLARE(switch_memory_pool_t *) switch_hash_pool_get(switch_hash_t * ht) -{ - return apr_hash_pool_get(ht); -} /* DSO functions */ @@ -367,9 +377,7 @@ SWITCH_DECLARE(switch_status_t) switch_file_exists(const char *filename, switch_ apr_finfo_t info = { 0 }; if (!pool) { - if ((apr_pool_create(&our_pool, NULL)) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_MEMERR; - } + switch_core_new_memory_pool(&our_pool); } if (filename) { @@ -380,7 +388,7 @@ SWITCH_DECLARE(switch_status_t) switch_file_exists(const char *filename, switch_ } if (our_pool) { - apr_pool_destroy(our_pool); + switch_core_destroy_memory_pool(&our_pool); } return status; diff --git a/src/switch_caller.c b/src/switch_caller.c index dc794ab426..a8bdc26ca5 100644 --- a/src/switch_caller.c +++ b/src/switch_caller.c @@ -32,6 +32,10 @@ #include #include + +#define profile_dup(a,b,p) if (!switch_strlen_zero(a)) { b = switch_core_strdup(p, a); } else { b = SWITCH_BLANK_STRING; } +#define profile_dup_clean(a,b,p) if (!switch_strlen_zero(a)) { b = switch_clean_string(switch_core_strdup(p, a)); } else { b = SWITCH_BLANK_STRING; } + SWITCH_DECLARE(switch_caller_profile_t *) switch_caller_profile_new(switch_memory_pool_t *pool, const char *username, const char *dialplan, @@ -40,32 +44,38 @@ SWITCH_DECLARE(switch_caller_profile_t *) switch_caller_profile_new(switch_memor const char *network_addr, const char *ani, const char *aniii, - const char *rdnis, const char *source, const char *context, + const char *rdnis, + const char *source, + const char *context, const char *destination_number) { switch_caller_profile_t *profile = NULL; - if ((profile = switch_core_alloc(pool, sizeof(switch_caller_profile_t))) != 0) { - if (!context) { - context = "default"; - } - profile->username = switch_clean_string(switch_core_strdup(pool, switch_str_nil(username))); - profile->dialplan = switch_clean_string(switch_core_strdup(pool, switch_str_nil(dialplan))); - profile->caller_id_name = switch_clean_string(switch_core_strdup(pool, switch_str_nil(caller_id_name))); - profile->caller_id_number = switch_clean_string(switch_core_strdup(pool, switch_str_nil(caller_id_number))); - profile->network_addr = switch_clean_string(switch_core_strdup(pool, switch_str_nil(network_addr))); - profile->ani = switch_clean_string(switch_core_strdup(pool, switch_str_nil(ani))); - profile->aniii = switch_clean_string(switch_core_strdup(pool, switch_str_nil(aniii))); - profile->rdnis = switch_clean_string(switch_core_strdup(pool, switch_str_nil(rdnis))); - profile->source = switch_clean_string(switch_core_strdup(pool, switch_str_nil(source))); - profile->context = switch_clean_string(switch_core_strdup(pool, switch_str_nil(context))); - profile->destination_number = switch_clean_string(switch_core_strdup(pool, switch_str_nil(destination_number))); - switch_set_flag(profile, SWITCH_CPF_SCREEN); - profile->pool = pool; + profile = switch_core_alloc(pool, sizeof(*profile)); + assert(profile != NULL); + + if (!context) { + context = "default"; } + profile_dup_clean(username, profile->username, pool); + profile_dup_clean(dialplan, profile->dialplan, pool); + profile_dup_clean(caller_id_name, profile->caller_id_name, pool); + profile_dup_clean(caller_id_number, profile->caller_id_number, pool); + profile_dup_clean(network_addr, profile->network_addr, pool); + profile_dup_clean(ani, profile->ani, pool); + profile_dup_clean(aniii, profile->aniii, pool); + profile_dup_clean(rdnis, profile->rdnis, pool); + profile_dup_clean(source, profile->source, pool); + profile_dup_clean(context, profile->context, pool); + profile_dup_clean(destination_number, profile->destination_number, pool); + profile->uuid = SWITCH_BLANK_STRING; + profile->chan_name = SWITCH_BLANK_STRING; + + switch_set_flag(profile, SWITCH_CPF_SCREEN); + profile->pool = pool; return profile; } @@ -74,31 +84,33 @@ SWITCH_DECLARE(switch_caller_profile_t *) switch_caller_profile_dup(switch_memor { switch_caller_profile_t *profile = NULL; - if ((profile = switch_core_alloc(pool, sizeof(switch_caller_profile_t))) != 0) { - profile->username = switch_core_strdup(pool, tocopy->username); - profile->dialplan = switch_core_strdup(pool, tocopy->dialplan); - profile->caller_id_name = switch_core_strdup(pool, tocopy->caller_id_name); - profile->ani = switch_core_strdup(pool, tocopy->ani); - profile->aniii = switch_core_strdup(pool, tocopy->aniii); - profile->caller_id_number = switch_core_strdup(pool, tocopy->caller_id_number); - profile->network_addr = switch_core_strdup(pool, tocopy->network_addr); - profile->rdnis = switch_core_strdup(pool, tocopy->rdnis); - profile->destination_number = switch_core_strdup(pool, tocopy->destination_number); - profile->uuid = switch_core_strdup(pool, tocopy->uuid); - profile->source = switch_core_strdup(pool, tocopy->source); - profile->context = switch_core_strdup(pool, tocopy->context); - profile->chan_name = switch_core_strdup(pool, tocopy->chan_name); - profile->caller_ton = tocopy->caller_ton; - profile->caller_numplan = tocopy->caller_numplan; - profile->ani_ton = tocopy->ani_ton; - profile->ani_numplan = tocopy->ani_numplan; - profile->rdnis_ton = tocopy->rdnis_ton; - profile->rdnis_numplan = tocopy->rdnis_numplan; - profile->destination_number_ton = tocopy->destination_number_ton; - profile->destination_number_numplan = tocopy->destination_number_numplan; - profile->flags = tocopy->flags; - profile->pool = pool; - } + profile = switch_core_alloc(pool, sizeof(*profile)); + assert(profile != NULL); + + profile_dup(tocopy->username, profile->username, pool); + profile_dup(tocopy->dialplan, profile->dialplan, pool); + profile_dup(tocopy->caller_id_name, profile->caller_id_name, pool); + profile_dup(tocopy->caller_id_number, profile->caller_id_number, pool); + profile_dup(tocopy->network_addr, profile->network_addr, pool); + profile_dup(tocopy->ani, profile->ani, pool); + profile_dup(tocopy->aniii, profile->aniii, pool); + profile_dup(tocopy->rdnis, profile->rdnis, pool); + profile_dup(tocopy->source, profile->source, pool); + profile_dup(tocopy->context, profile->context, pool); + profile_dup(tocopy->destination_number, profile->destination_number, pool); + profile_dup(tocopy->uuid, profile->uuid, pool); + profile_dup(tocopy->chan_name, profile->chan_name, pool); + + profile->caller_ton = tocopy->caller_ton; + profile->caller_numplan = tocopy->caller_numplan; + profile->ani_ton = tocopy->ani_ton; + profile->ani_numplan = tocopy->ani_numplan; + profile->rdnis_ton = tocopy->rdnis_ton; + profile->rdnis_numplan = tocopy->rdnis_numplan; + profile->destination_number_ton = tocopy->destination_number_ton; + profile->destination_number_numplan = tocopy->destination_number_numplan; + profile->flags = tocopy->flags; + profile->pool = pool; return profile; } diff --git a/src/switch_channel.c b/src/switch_channel.c index b787fdfd7a..c7ed7966ec 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -113,7 +113,7 @@ struct switch_channel { switch_caller_profile_t *caller_profile; const switch_state_handler_table_t *state_handlers[SWITCH_MAX_STATE_HANDLERS]; int state_handler_index; - switch_hash_t *variables; + switch_event_t *variables; switch_hash_t *private_hash; switch_call_cause_t hangup_cause; int vi; @@ -179,7 +179,8 @@ SWITCH_DECLARE(switch_status_t) switch_channel_alloc(switch_channel_t **channel, return SWITCH_STATUS_MEMERR; } - switch_core_hash_init(&(*channel)->variables, pool); + switch_event_create(&(*channel)->variables, SWITCH_EVENT_MESSAGE); + switch_core_hash_init(&(*channel)->private_hash, pool); switch_buffer_create_dynamic(&(*channel)->dtmf_buffer, 128, 128, 0); @@ -269,7 +270,10 @@ SWITCH_DECLARE(switch_size_t) switch_channel_dequeue_dtmf(switch_channel_t *chan SWITCH_DECLARE(void) switch_channel_uninit(switch_channel_t *channel) { + switch_buffer_destroy(&channel->dtmf_buffer); + switch_core_hash_destroy(&channel->private_hash); + switch_event_destroy(&channel->variables); } SWITCH_DECLARE(switch_status_t) switch_channel_init(switch_channel_t *channel, switch_core_session_t *session, switch_channel_state_t state, @@ -320,7 +324,7 @@ SWITCH_DECLARE(char *) switch_channel_get_variable(switch_channel_t *channel, co assert(channel != NULL); switch_mutex_lock(channel->profile_mutex); - if (!(v = switch_core_hash_find(channel->variables, varname))) { + if (!(v = switch_event_get_header(channel->variables, (char*)varname))) { if (!channel->caller_profile || !(v = switch_caller_get_field_by_name(channel->caller_profile, varname))) { if (!strcmp(varname, "base_dir")) { v = SWITCH_GLOBAL_dirs.base_dir; @@ -339,30 +343,32 @@ SWITCH_DECLARE(void) switch_channel_variable_last(switch_channel_t *channel) assert(channel != NULL); if (channel->vi) { switch_mutex_unlock(channel->profile_mutex); + channel->vi = 0; } } -SWITCH_DECLARE(switch_hash_index_t *) switch_channel_variable_first(switch_channel_t *channel) +SWITCH_DECLARE(switch_event_header_t *) switch_channel_variable_first(switch_channel_t *channel) { - switch_hash_index_t *hi; + switch_event_header_t *hi; assert(channel != NULL); - - switch_mutex_lock(channel->profile_mutex); - if ((hi = switch_hash_first(NULL, channel->variables))) { - channel->vi = 1; - } else { - switch_mutex_unlock(channel->profile_mutex); + if (channel->vi) { + return NULL; } + switch_mutex_lock(channel->profile_mutex); + channel->vi = 1; + return channel->variables->headers; + return hi; + } SWITCH_DECLARE(switch_status_t) switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info) { assert(channel != NULL); switch_mutex_lock(channel->profile_mutex); - switch_core_hash_insert_dup_locked(channel->private_hash, switch_core_session_strdup(channel->session, key), private_info, channel->profile_mutex); + switch_core_hash_insert_locked(channel->private_hash, key, private_info, channel->profile_mutex); switch_mutex_unlock(channel->profile_mutex); return SWITCH_STATUS_SUCCESS; } @@ -399,31 +405,14 @@ SWITCH_DECLARE(char *) switch_channel_get_name(switch_channel_t *channel) SWITCH_DECLARE(switch_status_t) switch_channel_set_variable(switch_channel_t *channel, const char *varname, const char *value) { assert(channel != NULL); - + if (!switch_strlen_zero(varname)) { switch_mutex_lock(channel->profile_mutex); - switch_core_hash_delete(channel->variables, varname); - if (!switch_strlen_zero(value)) { - switch_core_hash_insert_dup(channel->variables, varname, - switch_clean_string(switch_core_session_strdup(channel->session, value))); - } - switch_mutex_unlock(channel->profile_mutex); - return SWITCH_STATUS_SUCCESS; - } - - return SWITCH_STATUS_FALSE; -} - -SWITCH_DECLARE(switch_status_t) switch_channel_set_variable_nodup(switch_channel_t *channel, const char *varname, char *value) -{ - assert(channel != NULL); - - if (!switch_strlen_zero(varname)) { - switch_mutex_lock(channel->profile_mutex); - switch_core_hash_delete(channel->variables, varname); - if (!switch_strlen_zero(value)) { - switch_core_hash_insert_dup(channel->variables, varname, value); - } + if (value) { + switch_event_add_header(channel->variables, SWITCH_STACK_BOTTOM, varname, "%s", value); + } else { + switch_event_del_header(channel->variables, varname); + } switch_mutex_unlock(channel->profile_mutex); return SWITCH_STATUS_SUCCESS; } @@ -739,7 +728,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c snprintf(state_num, sizeof(state_num), "%d", channel->state); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-State", "%s", (char *) switch_channel_state_name(channel->state)); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-State-Number", "%s", (char *) state_num); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Name", "%s", switch_channel_get_name(channel)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Name", "%s", channel->name); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Unique-ID", "%s", switch_core_session_get_uuid(channel->session)); } switch_event_fire(&event); @@ -775,12 +764,10 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c SWITCH_DECLARE(void) switch_channel_event_set_data(switch_channel_t *channel, switch_event_t *event) { switch_caller_profile_t *caller_profile, *originator_caller_profile = NULL, *originatee_caller_profile = NULL; - switch_hash_index_t *hi; + switch_event_header_t *hi; switch_codec_t *codec; - void *val; - const void *var; char state_num[25]; - + int x; switch_mutex_lock(channel->profile_mutex); if ((caller_profile = switch_channel_get_caller_profile(channel))) { @@ -818,15 +805,20 @@ SWITCH_DECLARE(void) switch_channel_event_set_data(switch_channel_t *channel, sw if (originatee_caller_profile) { switch_caller_profile_event_set_data(originatee_caller_profile, "Originatee", event); } - + x = 0; /* Index Variables */ - for (hi = switch_hash_first(NULL, channel->variables); hi; hi = switch_hash_next(hi)) { + for (hi = channel->variables->headers; hi; hi = hi->next) { char buf[1024]; - switch_hash_this(hi, &var, NULL, &val); - if (var && val) { - snprintf(buf, sizeof(buf), "variable_%s", (char *) var); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, buf, "%s", (char *) val); - } + char *vvar = NULL, *vval = NULL; + + vvar = (char *) hi->name; + vval = (char *) hi->value; + x++; + + assert(vvar && vval); + snprintf(buf, sizeof(buf), "variable_%s", vvar); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, buf, "%s", vval); + } switch_mutex_unlock(channel->profile_mutex); @@ -893,23 +885,25 @@ SWITCH_DECLARE(switch_caller_profile_t *) switch_channel_get_caller_profile(swit SWITCH_DECLARE(void) switch_channel_set_originator_caller_profile(switch_channel_t *channel, switch_caller_profile_t *caller_profile) { assert(channel != NULL); + switch_mutex_lock(channel->profile_mutex); if (channel->caller_profile) { - switch_mutex_lock(channel->profile_mutex); caller_profile->next = channel->caller_profile->originator_caller_profile; channel->caller_profile->originator_caller_profile = caller_profile; - switch_mutex_unlock(channel->profile_mutex); } + switch_mutex_unlock(channel->profile_mutex); } SWITCH_DECLARE(void) switch_channel_set_originatee_caller_profile(switch_channel_t *channel, switch_caller_profile_t *caller_profile) { assert(channel != NULL); + + switch_mutex_lock(channel->profile_mutex); if (channel->caller_profile) { - switch_mutex_lock(channel->profile_mutex); caller_profile->next = channel->caller_profile->originatee_caller_profile; channel->caller_profile->originatee_caller_profile = caller_profile; - switch_mutex_unlock(channel->profile_mutex); } + switch_mutex_unlock(channel->profile_mutex); + } SWITCH_DECLARE(switch_caller_profile_t *) switch_channel_get_originator_caller_profile(switch_channel_t *channel) @@ -917,12 +911,12 @@ SWITCH_DECLARE(switch_caller_profile_t *) switch_channel_get_originator_caller_p switch_caller_profile_t *profile = NULL; assert(channel != NULL); + switch_mutex_lock(channel->profile_mutex); if (channel->caller_profile) { - switch_mutex_lock(channel->profile_mutex); profile = channel->caller_profile->originator_caller_profile; - switch_mutex_unlock(channel->profile_mutex); } - + switch_mutex_unlock(channel->profile_mutex); + return profile; } @@ -931,12 +925,12 @@ SWITCH_DECLARE(switch_caller_profile_t *) switch_channel_get_originatee_caller_p switch_caller_profile_t *profile = NULL; assert(channel != NULL); + switch_mutex_lock(channel->profile_mutex); if (channel->caller_profile) { - switch_mutex_lock(channel->profile_mutex); profile = channel->caller_profile->originatee_caller_profile; - switch_mutex_unlock(channel->profile_mutex); } - + switch_mutex_unlock(channel->profile_mutex); + return profile; } diff --git a/src/switch_core.c b/src/switch_core.c index 3bee96b3ef..3237f89c08 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -394,13 +394,13 @@ SWITCH_DECLARE(void) switch_core_runtime_loop(int bg) } -SWITCH_DECLARE(switch_status_t) switch_core_init(const char *console, const char **err) +SWITCH_DECLARE(switch_status_t) switch_core_init(const char *console, switch_core_flag_t flags, const char **err) { switch_xml_t xml = NULL, cfg = NULL; switch_uuid_t uuid; memset(&runtime, 0, sizeof(runtime)); - runtime.no_new_sessions = 1; + switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); /* INIT APR and Create the pool context */ if (apr_initialize() != SWITCH_STATUS_SUCCESS) { @@ -417,7 +417,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(const char *console, const char switch_core_set_globals(); switch_core_session_init(runtime.memory_pool); switch_core_hash_init(&runtime.global_vars, runtime.memory_pool); - + runtime.flags = flags; if (switch_xml_init(runtime.memory_pool, err) != SWITCH_STATUS_SUCCESS) { @@ -435,7 +435,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(const char *console, const char const char *val = switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "crash-protection")) { - runtime.crash_prot = switch_true(val); + if (switch_true(val)) { + switch_set_flag((&runtime), SCF_CRASH_PROT); + } } else if (!strcasecmp(var, "max-sessions")) { switch_core_session_limit(atoi(val)); } @@ -485,7 +487,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(const char *console, const char switch_log_init(runtime.memory_pool); switch_event_init(runtime.memory_pool); - switch_core_sqldb_start(runtime.memory_pool); + if (switch_test_flag((&runtime), SCF_USE_SQL)) { + switch_core_sqldb_start(runtime.memory_pool); + } switch_rtp_init(runtime.memory_pool); runtime.running = 1; @@ -542,10 +546,10 @@ static void handle_SIGINT(int sig) if (sig); return; } -SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(const char *console, const char **err) +SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(const char *console, switch_core_flag_t flags, const char **err) { switch_event_t *event; - if (switch_core_init(console, err) != SWITCH_STATUS_SUCCESS) { + if (switch_core_init(console, flags, err) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_GENERR; } @@ -578,11 +582,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(const char *console } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, - "\nFreeSWITCH Version %s Started.\nCrash Protection [%s]\nMax Sessions[%u]\n\n", SWITCH_VERSION_FULL, - runtime.crash_prot ? "Enabled" : "Disabled", - switch_core_session_limit(0)); + "\nFreeSWITCH Version %s Started.\nCrash Protection [%s]\nMax Sessions[%u]\nSQL [%s]\n", SWITCH_VERSION_FULL, + switch_test_flag((&runtime), SCF_CRASH_PROT) ? "Enabled" : "Disabled", + switch_core_session_limit(0), + switch_test_flag((&runtime), SCF_USE_SQL) ? "Enabled" : "Disabled" + ); - runtime.no_new_sessions = 0; + switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS); return SWITCH_STATUS_SUCCESS; @@ -612,13 +618,17 @@ SWITCH_DECLARE(switch_time_t) switch_core_uptime(void) SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, uint32_t * val) { - if (runtime.shutting_down) { + if (switch_test_flag((&runtime), SCF_SHUTTING_DOWN)) { return -1; } switch (cmd) { case SCSC_PAUSE_INBOUND: - runtime.no_new_sessions = *val; + if (*val) { + switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); + } else { + switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS); + } break; case SCSC_HUPALL: switch_core_session_hupall(SWITCH_CAUSE_MANAGER_REQUEST); @@ -634,9 +644,15 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, uint32 return 0; } + +SWITCH_DECLARE(switch_core_flag_t) switch_core_flags(void) +{ + return runtime.flags; +} + SWITCH_DECLARE(switch_bool_t) switch_core_ready(void) { - return (runtime.shutting_down || runtime.no_new_sessions) ? SWITCH_FALSE : SWITCH_TRUE; + return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE; } @@ -647,8 +663,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void) switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Shutting Down"); switch_event_fire(&event); } - runtime.shutting_down = 1; - runtime.no_new_sessions = 1; + + switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); + switch_set_flag((&runtime), SCF_SHUTTING_DOWN); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "End existing sessions\n"); @@ -659,10 +676,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Closing Event Engine.\n"); switch_event_shutdown(); - switch_core_sqldb_stop(); + if (switch_test_flag((&runtime), SCF_USE_SQL)) { + switch_core_sqldb_stop(); + } switch_scheduler_task_thread_stop(); switch_xml_destroy(); + switch_core_memory_stop(); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Finalizing Shutdown.\n"); switch_log_shutdown(); @@ -683,6 +703,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void) switch_safe_free(SWITCH_GLOBAL_dirs.grammar_dir); switch_safe_free(SWITCH_GLOBAL_dirs.temp_dir); + + switch_core_hash_destroy(&runtime.global_vars); + if (runtime.memory_pool) { apr_pool_destroy(runtime.memory_pool); /* apr_terminate(); */ diff --git a/src/switch_core_hash.c b/src/switch_core_hash.c index c03a442048..c9902826fe 100644 --- a/src/switch_core_hash.c +++ b/src/switch_core_hash.c @@ -33,49 +33,40 @@ */ #include #include "private/switch_core_pvt.h" +#include +#include "../../../libs/sqlite/src/hash.h" + + +struct switch_hash { + Hash table; +}; + SWITCH_DECLARE(switch_status_t) switch_core_hash_init(switch_hash_t ** hash, switch_memory_pool_t *pool) { - assert(pool != NULL); + switch_hash_t *newhash; + + newhash = switch_core_alloc(pool, sizeof(*newhash)); + assert(newhash); - if ((*hash = apr_hash_make(pool)) != 0) { - return SWITCH_STATUS_SUCCESS; - } - - return SWITCH_STATUS_GENERR; -} - -SWITCH_DECLARE(switch_status_t) switch_core_hash_destroy(switch_hash_t * hash) -{ - assert(hash != NULL); + sqlite3HashInit(&newhash->table, SQLITE_HASH_STRING, 1); + *hash = newhash; + return SWITCH_STATUS_SUCCESS; + } -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_destroy(switch_hash_t **hash) { - apr_hash_set(hash, switch_core_strdup(apr_hash_pool_get(hash), key), APR_HASH_KEY_STRING, data); - 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); - } - - + assert(hash != NULL && *hash != NULL); + sqlite3HashClear(&(*hash)->table); + *hash = NULL; return SWITCH_STATUS_SUCCESS; } 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); + sqlite3HashInsert(&hash->table, key, strlen(key)+1, (void *)data); return SWITCH_STATUS_SUCCESS; } @@ -84,8 +75,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_insert_locked(switch_hash_t * h if (mutex) { switch_mutex_lock(mutex); } - - apr_hash_set(hash, key, APR_HASH_KEY_STRING, data); + + sqlite3HashInsert(&hash->table, key, strlen(key)+1, (void *)data); if (mutex) { switch_mutex_unlock(mutex); @@ -96,7 +87,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_insert_locked(switch_hash_t * h 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); + sqlite3HashInsert(&hash->table, key, strlen(key)+1, NULL); return SWITCH_STATUS_SUCCESS; } @@ -106,8 +97,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_locked(switch_hash_t * h switch_mutex_lock(mutex); } - apr_hash_set(hash, key, APR_HASH_KEY_STRING, NULL); - + sqlite3HashInsert(&hash->table, key, strlen(key)+1, NULL); + if (mutex) { switch_mutex_unlock(mutex); } @@ -118,7 +109,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_locked(switch_hash_t * h 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 sqlite3HashFind(&hash->table, key, strlen(key)+1); } SWITCH_DECLARE(void *) switch_core_hash_find_locked(switch_hash_t * hash, const char *key, switch_mutex_t *mutex) @@ -129,11 +120,36 @@ SWITCH_DECLARE(void *) switch_core_hash_find_locked(switch_hash_t * hash, const switch_mutex_lock(mutex); } - val = apr_hash_get(hash, key, APR_HASH_KEY_STRING); - + val = sqlite3HashFind(&hash->table, key, strlen(key)+1); + if (mutex) { switch_mutex_unlock(mutex); } return val; } + + +SWITCH_DECLARE(switch_hash_index_t *) switch_hash_first(char *depricate_me, switch_hash_t *hash) +{ + return (switch_hash_index_t *) sqliteHashFirst(&hash->table); +} + + +SWITCH_DECLARE(switch_hash_index_t *) switch_hash_next(switch_hash_index_t *hi) +{ + return (switch_hash_index_t *) sqliteHashNext((HashElem *) hi); +} + +SWITCH_DECLARE(void) switch_hash_this(switch_hash_index_t *hi, const void **key, switch_ssize_t *klen, void **val) +{ + if (key) { + *key = sqliteHashKey((HashElem *) hi); + } + if (klen) { + *klen = strlen((char *) *key) + 1; + } + if (val) { + *val = sqliteHashData((HashElem *) hi); + } +} diff --git a/src/switch_core_memory.c b/src/switch_core_memory.c index 0264a42f6a..9aefc01cb5 100644 --- a/src/switch_core_memory.c +++ b/src/switch_core_memory.c @@ -33,13 +33,19 @@ */ #include #include "private/switch_core_pvt.h" +/*#define LOCK_MORE*/ static struct { + switch_mutex_t *mem_lock; + switch_queue_t *pool_queue; /* 8 ball break */ switch_memory_pool_t *memory_pool; + int pool_thread_running; } memory_manager; SWITCH_DECLARE(switch_memory_pool_t *) switch_core_session_get_pool(switch_core_session_t *session) { + assert(session != NULL); + assert(session->pool != NULL); return session->pool; } @@ -51,14 +57,23 @@ SWITCH_DECLARE(void *) switch_core_session_alloc(switch_core_session_t *session, assert(session != NULL); assert(session->pool != NULL); -#ifdef DEBUG_ALLOC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Allocate %d\n", memory); +#ifdef LOCK_MORE + switch_mutex_lock(memory_manager.mem_lock); #endif +#ifdef DEBUG_ALLOC + printf("Allocate %d\n", (int)memory); +#endif + + ptr = apr_palloc(session->pool, memory); + assert(ptr != NULL); + + memset(ptr, 0, memory); + +#ifdef LOCK_MORE + switch_mutex_unlock(memory_manager.mem_lock); +#endif - if ((ptr = apr_palloc(session->pool, memory)) != 0) { - memset(ptr, 0, memory); - } return ptr; } @@ -70,14 +85,23 @@ SWITCH_DECLARE(void *) switch_core_permanent_alloc(switch_size_t memory) void *ptr = NULL; assert(memory_manager.memory_pool != NULL); - -#ifdef DEBUG_ALLOC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Perm Allocate %d\n", memory); +#ifdef LOCK_MORE + switch_mutex_lock(memory_manager.mem_lock); +#endif + +#ifdef DEBUG_ALLOC + printf("Perm Allocate %d\n", (int)memory); +#endif + + ptr = apr_palloc(memory_manager.memory_pool, memory); + + assert(ptr != NULL); + memset(ptr, 0, memory); + +#ifdef LOCK_MORE + switch_mutex_unlock(memory_manager.mem_lock); #endif - if ((ptr = apr_palloc(memory_manager.memory_pool, memory)) != 0) { - memset(ptr, 0, memory); - } return ptr; } @@ -90,15 +114,22 @@ SWITCH_DECLARE(char *) switch_core_permanent_strdup(const char *todup) if (!todup) return NULL; - len = strlen(todup) + 1; - -#ifdef DEBUG_ALLOC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Perm Allocate %d\n", len); +#ifdef LOCK_MORE + switch_mutex_lock(memory_manager.mem_lock); +#endif + + len = strlen(todup) + 1; + duped = apr_pstrmemdup(memory_manager.memory_pool, todup, len); + assert(duped != NULL); + +#ifdef DEBUG_ALLOC + printf("Perm Allocate %d\n", (int)len); +#endif + +#ifdef LOCK_MORE + switch_mutex_unlock(memory_manager.mem_lock); #endif - if (todup && (duped = apr_palloc(memory_manager.memory_pool, len)) != 0) { - strncpy(duped, todup, len); - } return duped; } @@ -107,14 +138,23 @@ SWITCH_DECLARE(char *) switch_core_session_sprintf(switch_core_session_t *sessio va_list ap; char *result = NULL; +#ifdef LOCK_MORE + switch_mutex_lock(memory_manager.mem_lock); +#endif + assert(session != NULL); assert(session->pool != NULL); va_start(ap, fmt); - + result = apr_pvsprintf(session->pool, fmt, ap); - + assert(result != NULL); va_end(ap); + +#ifdef LOCK_MORE + switch_mutex_unlock(memory_manager.mem_lock); +#endif + return result; } @@ -124,12 +164,21 @@ SWITCH_DECLARE(char *) switch_core_sprintf(switch_memory_pool_t *pool, const cha char *result = NULL; assert(pool != NULL); + +#ifdef LOCK_MORE + switch_mutex_lock(memory_manager.mem_lock); +#endif + va_start(ap, fmt); result = apr_pvsprintf(pool, fmt, ap); - + assert(result != NULL); va_end(ap); +#ifdef LOCK_MORE + switch_mutex_unlock(memory_manager.mem_lock); +#endif + return result; } @@ -144,15 +193,25 @@ SWITCH_DECLARE(char *) switch_core_session_strdup(switch_core_session_t *session if (!todup) { return NULL; } + +#ifdef LOCK_MORE + switch_mutex_lock(memory_manager.mem_lock); +#endif + len = strlen(todup) + 1; #ifdef DEBUG_ALLOC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Allocate %d\n", len); + printf("Allocate %d\n", (int)len); +#endif + + duped = apr_pstrmemdup(session->pool, todup, len); + assert(duped != NULL); + + +#ifdef LOCK_MORE + switch_mutex_unlock(memory_manager.mem_lock); #endif - if (todup && (duped = apr_palloc(session->pool, len)) != 0) { - strncpy(duped, todup, len); - } return duped; } @@ -167,31 +226,61 @@ SWITCH_DECLARE(char *) switch_core_strdup(switch_memory_pool_t *pool, const char return NULL; } +#ifdef LOCK_MORE + switch_mutex_lock(memory_manager.mem_lock); +#endif + len = strlen(todup) + 1; #ifdef DEBUG_ALLOC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Allocate %d\n", len); + printf("Allocate %d\n", (int)len); +#endif + + duped = apr_pstrmemdup(pool, todup, len); + assert(duped != NULL); + +#ifdef LOCK_MORE + switch_mutex_unlock(memory_manager.mem_lock); #endif - if (todup && (duped = apr_palloc(pool, len)) != 0) { - strncpy(duped, todup, len); - } return duped; } -SWITCH_DECLARE(switch_status_t) switch_core_new_memory_pool(switch_memory_pool_t **pool) +SWITCH_DECLARE(switch_status_t) switch_core_perform_new_memory_pool(switch_memory_pool_t **pool, const char *file, const char *func, int line) { + char *tmp; - if ((apr_pool_create(pool, NULL)) != SWITCH_STATUS_SUCCESS) { - *pool = NULL; - return SWITCH_STATUS_MEMERR; - } + switch_mutex_lock(memory_manager.mem_lock); + assert(pool != NULL); + + apr_pool_create(pool, NULL); + assert(*pool != NULL); + +#ifdef DEBUG_ALLOC2 + printf("New Pool %s %s:%d\n", file, func, line); +#endif + tmp = switch_core_sprintf(*pool, "%s:%d", func, line); + apr_pool_tag(*pool, tmp); + switch_mutex_unlock(memory_manager.mem_lock); return SWITCH_STATUS_SUCCESS; } -SWITCH_DECLARE(switch_status_t) switch_core_destroy_memory_pool(switch_memory_pool_t **pool) +SWITCH_DECLARE(switch_status_t) switch_core_perform_destroy_memory_pool(switch_memory_pool_t **pool, const char *file, const char *func, int line) { - apr_pool_destroy(*pool); + //char tmp[128] = ""; + + + assert(pool != NULL); + +#ifdef DEBUG_ALLOC2 + printf("Free Pool %s %s:%d\n", file, func, line); +#endif + + switch_queue_push(memory_manager.pool_queue, *pool); + //apr_pool_destroy(*pool); + *pool = NULL; + + return SWITCH_STATUS_SUCCESS; } @@ -199,23 +288,108 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy_memory_pool(switch_memory_po SWITCH_DECLARE(void *) switch_core_alloc(switch_memory_pool_t *pool, switch_size_t memory) { void *ptr = NULL; + assert(pool != NULL); -#ifdef DEBUG_ALLOC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Allocate %d\n", memory); - /* assert(memory < 600000); */ +#ifdef LOCK_MORE + switch_mutex_lock(memory_manager.mem_lock); +#endif + +#ifdef DEBUG_ALLOC + printf("Allocate %d\n", (int)memory); + /*assert(memory < 20000);*/ +#endif + + ptr = apr_palloc(pool, memory); + assert(ptr != NULL); + memset(ptr, 0, memory); + + +#ifdef LOCK_MORE + switch_mutex_unlock(memory_manager.mem_lock); #endif - if ((ptr = apr_palloc(pool, memory)) != 0) { - memset(ptr, 0, memory); - } return ptr; } + +static void *SWITCH_THREAD_FUNC pool_thread(switch_thread_t * thread, void *obj) +{ + void *pop = NULL; + switch_memory_pool_t *pool; + + memory_manager.pool_thread_running = 1; + + while (memory_manager.pool_thread_running == 1) { + int len = switch_queue_size(memory_manager.pool_queue); + + if (len) { + int x = len, done = 0; + + switch_yield(1000000); + switch_mutex_lock(memory_manager.mem_lock); + while (x > 0) { + if (switch_queue_pop(memory_manager.pool_queue, &pop) != SWITCH_STATUS_SUCCESS) { + done = 1; + break; + } + + if (!pop) { + done = 1; + break; + } + + pool = (switch_memory_pool_t *) pop; + apr_pool_destroy(pool); + pool = NULL; + x--; + } + switch_mutex_unlock(memory_manager.mem_lock); + if (done) { + goto done; + } + } else { + switch_yield(100000); + } + } + + done: + memory_manager.pool_thread_running = 0; + return NULL; +} + + +void switch_core_memory_stop(void) +{ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Stopping memory pool queue.\n"); + switch_queue_push(memory_manager.pool_queue, NULL); + while(memory_manager.pool_thread_running) { + switch_yield(1000); + } +} + switch_memory_pool_t *switch_core_memory_init(void) { + switch_thread_t *thread; + switch_threadattr_t *thd_attr; + + memset(&memory_manager, 0, sizeof(memory_manager)); apr_pool_create(&memory_manager.memory_pool, NULL); + assert(memory_manager.memory_pool != NULL); + switch_mutex_init(&memory_manager.mem_lock, SWITCH_MUTEX_NESTED, memory_manager.memory_pool); + switch_queue_create(&memory_manager.pool_queue, 50000, memory_manager.memory_pool); + + switch_threadattr_create(&thd_attr, memory_manager.memory_pool); + switch_threadattr_detach_set(thd_attr, 1); + + switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_thread_create(&thread, thd_attr, pool_thread, NULL, memory_manager.memory_pool); + + while (!memory_manager.pool_thread_running) { + switch_yield(1000); + } + return memory_manager.memory_pool; } diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 2f40faa921..c374b35a66 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -306,11 +306,11 @@ SWITCH_DECLARE(switch_call_cause_t) switch_core_session_outgoing_channel(switch_ switch_channel_set_originatee_caller_profile(channel, cloned_profile); } } - } - if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_OUTGOING) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(peer_channel, event); - switch_event_fire(&event); + if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_OUTGOING) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(peer_channel, event); + switch_event_fire(&event); + } } } @@ -664,13 +664,12 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t * switch_channel_uninit((*session)->channel); pool = (*session)->pool; -#ifndef NDEBUG - memset(*session, 0, sizeof(switch_core_session_t)); -#endif + //#ifndef NDEBUG + //memset(*session, 0, sizeof(switch_core_session_t)); + //#endif *session = NULL; - apr_pool_destroy(pool); - pool = NULL; - + switch_core_destroy_memory_pool(&pool); + } static void *SWITCH_THREAD_FUNC switch_core_session_thread(switch_thread_t * thread, void *obj) @@ -770,13 +769,13 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request(const switch if ((session = switch_core_alloc(usepool, sizeof(switch_core_session_t))) == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate session\n"); - apr_pool_destroy(usepool); + switch_core_destroy_memory_pool(&usepool); return NULL; } if (switch_channel_alloc(&session->channel, usepool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate channel structure\n"); - apr_pool_destroy(usepool); + switch_core_destroy_memory_pool(&usepool); return NULL; } @@ -883,6 +882,10 @@ void switch_core_session_init(switch_memory_pool_t *pool) switch_mutex_init(&session_manager.session_table_mutex, SWITCH_MUTEX_NESTED, session_manager.memory_pool); } +void switch_core_session_uninit(void) +{ + switch_core_hash_destroy(&session_manager.session_table); +} SWITCH_DECLARE(switch_app_log_t *) switch_core_session_get_app_log(switch_core_session_t *session) { diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index b404483e11..7ba0b1181c 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -276,7 +276,7 @@ static void core_event_handler(switch_event_t *event) case CS_DONE: break; case CS_RING: - sql = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',ip_addr='%s',dest='%q'" + sql = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',ip_addr='%s',dest='%q' " "where uuid='%s'", switch_event_get_header(event, "channel-state"), switch_event_get_header(event, "caller-caller-id-name"), diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index b0d2b1fa06..6b2ca1669e 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -210,7 +210,12 @@ static void switch_core_standard_on_hibernate(switch_core_session_t *session) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Standard HIBERNATE\n"); } -static switch_hash_t *stack_table = NULL; +#include +#include "../../../libs/sqlite/src/hash.h" + +//static switch_hash_t *stack_table = NULL; +static Hash stack_table; + #if defined (__GNUC__) && defined (LINUX) #include #include @@ -250,7 +255,8 @@ static void handle_fatality(int sig) jmp_buf *env; if (sig && (thread_id = switch_thread_self()) - && (env = (jmp_buf *) apr_hash_get(stack_table, &thread_id, sizeof(thread_id)))) { + && (env = (jmp_buf *) sqlite3HashFind(&stack_table, &thread_id, sizeof(thread_id)))) { + //&& (env = (jmp_buf *) switch_core_hash_find(stack_table, (char *)&thread_id, sizeof(thread_id)))) { print_trace(); longjmp(*env, sig); } else { @@ -262,8 +268,9 @@ static void handle_fatality(int sig) void switch_core_state_machine_init(switch_memory_pool_t *pool) { - if (runtime.crash_prot) { - switch_core_hash_init(&stack_table, pool); + + if (switch_test_flag((&runtime), SCF_CRASH_PROT)) { + sqlite3HashInit(&stack_table, SQLITE_HASH_BINARY, 0); } } @@ -277,7 +284,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) jmp_buf env; int sig; - if (runtime.crash_prot) { + if (switch_test_flag((&runtime), SCF_CRASH_PROT)) { thread_id = switch_thread_self(); signal(SIGSEGV, handle_fatality); signal(SIGFPE, handle_fatality); @@ -295,7 +302,8 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Thread has crashed for channel %s\n", switch_channel_get_name(session->channel)); switch_channel_hangup(session->channel, SWITCH_CAUSE_CRASH); } else { - apr_hash_set(stack_table, &thread_id, sizeof(thread_id), &env); + sqlite3HashInsert(&stack_table, &thread_id, sizeof(thread_id), (void *)&env); + //apr_hash_set(stack_table, &thread_id, sizeof(thread_id), &env); } } @@ -686,8 +694,9 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) done: switch_mutex_unlock(session->mutex); - if (runtime.crash_prot) { - apr_hash_set(stack_table, &thread_id, sizeof(thread_id), NULL); + if (switch_test_flag((&runtime), SCF_CRASH_PROT)) { + sqlite3HashInsert(&stack_table, &thread_id, sizeof(thread_id), NULL); + //apr_hash_set(stack_table, &thread_id, sizeof(thread_id), NULL); } session->thread_running = 0; diff --git a/src/switch_event.c b/src/switch_event.c index 3788a811df..ac5d826dd1 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -77,16 +77,24 @@ static void *locked_dup(char *str) return dup; } - #define ALLOC(size) locked_alloc(size) #define DUP(str) locked_dup(str) #endif +static char *my_dup (const char *s) +{ + size_t len = strlen (s) + 1; + void *new = malloc (len); + assert(new); + + return (char *) memcpy (new, s, len); +} + #ifndef ALLOC #define ALLOC(size) malloc(size) #endif #ifndef DUP -#define DUP(str) strdup(str) +#define DUP(str) my_dup(str) #endif #ifndef FREE #define FREE(ptr) if (ptr) free(ptr) @@ -393,6 +401,9 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void) last = THREAD_RUNNING; } } + + switch_core_hash_destroy(&CUSTOM_HASH); + return SWITCH_STATUS_SUCCESS; } @@ -494,14 +505,38 @@ SWITCH_DECLARE(char *) switch_event_get_body(switch_event_t *event) return NULL; } +SWITCH_DECLARE(switch_status_t) switch_event_del_header(switch_event_t *event, const char *header_name) +{ + switch_event_header_t *hp, *lp = NULL; + switch_status_t status = SWITCH_STATUS_FALSE; + + for (hp = event->headers; hp && hp->next; hp = hp->next) { + if (!strcmp(header_name, hp->name)) { + if (lp) { + lp->next = hp->next; + } else { + event->headers = hp->next; + } + FREE(hp->name); + FREE(hp->value); + FREE(hp); + status = SWITCH_STATUS_SUCCESS; + break; + } + lp = hp; + } + + return status; +} + SWITCH_DECLARE(switch_status_t) switch_event_add_header(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *fmt, ...) { int ret = 0; - char data[2048]; - + char *data; va_list ap; + va_start(ap, fmt); - ret = vsnprintf(data, sizeof(data), fmt, ap); + ret = switch_vasprintf(&data, fmt, ap); va_end(ap); if (ret == -1) { @@ -516,7 +551,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_add_header(switch_event_t *event, s memset(header, 0, sizeof(*header)); header->name = DUP(header_name); - header->value = DUP(data); + header->value = data; if (stack == SWITCH_STACK_TOP) { header->next = event->headers; event->headers = header; diff --git a/src/switch_ivr.c b/src/switch_ivr.c index eae808c822..6e171f2b85 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -266,7 +266,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se switch_channel_t *channel = switch_core_session_get_channel(session); char *cmd = switch_event_get_header(event, "call-command"); unsigned long cmd_hash; - switch_ssize_t hlen = SWITCH_HASH_KEY_STRING; + switch_ssize_t hlen = -1; unsigned long CMD_EXECUTE = switch_hashfunc_default("execute", &hlen); unsigned long CMD_HANGUP = switch_hashfunc_default("hangup", &hlen); unsigned long CMD_NOMEDIA = switch_hashfunc_default("nomedia", &hlen); @@ -856,53 +856,44 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_ char *uuid = NULL; assert(session != NULL); - assert(extension != NULL); - switch_core_session_reset(session); - channel = switch_core_session_get_channel(session); assert(channel != NULL); /* clear all state handlers */ switch_channel_clear_state_handler(channel, NULL); + if (switch_strlen_zero(dialplan)) { + dialplan = "XML"; + } + + if (switch_strlen_zero(context)) { + context = "default"; + } + + if (switch_strlen_zero(extension)) { + extension = "service"; + } + if ((profile = switch_channel_get_caller_profile(channel))) { new_profile = switch_caller_profile_clone(session, profile); + + new_profile->dialplan = switch_core_session_strdup(session, dialplan); + new_profile->context = switch_core_session_strdup(session, context); new_profile->destination_number = switch_core_session_strdup(session, extension); - if (!switch_strlen_zero(dialplan)) { - new_profile->dialplan = switch_core_session_strdup(session, dialplan); - } else { - dialplan = new_profile->dialplan; - } - - if (!switch_strlen_zero(context)) { - new_profile->context = switch_core_session_strdup(session, context); - } else { - context = new_profile->context; - } - - if (switch_strlen_zero(context)) { - context = "default"; - } - - if (switch_strlen_zero(dialplan)) { - context = "XML"; - } - - switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, NULL); /* If HANGUP_AFTER_BRIDGE is set to 'true', SWITCH_SIGNAL_BRIDGE_VARIABLE * will not have a value, so we need to check SWITCH_BRIDGE_VARIABLE */ uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE); - + if(!uuid) { uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE); } - + if (uuid && (other_session = switch_core_session_locate(uuid))) { switch_channel_set_variable(other_channel, SWITCH_SIGNAL_BOND_VARIABLE, NULL); switch_core_session_rwunlock(other_session); @@ -915,7 +906,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_ switch_channel_set_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, NULL); switch_channel_set_variable(other_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, NULL); - + switch_channel_set_variable(channel, SWITCH_BRIDGE_VARIABLE, NULL); switch_channel_set_variable(other_channel, SWITCH_BRIDGE_VARIABLE, NULL); @@ -932,7 +923,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_ switch_channel_set_flag(channel, CF_TRANSFER); switch_channel_set_state(channel, CS_RING); - + msg.message_id = SWITCH_MESSAGE_INDICATE_TRANSFER; msg.from = __FILE__; switch_core_session_receive_message(session, &msg); @@ -963,13 +954,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_transfer_variable(switch_core_session switch_channel_set_variable(chanb, var, val); } } else { - switch_hash_index_t *hi; - void *vval; - const void *vvar; - + switch_event_header_t *hi; if ((hi = switch_channel_variable_first(chana))) { - for (; hi; hi = switch_hash_next(hi)) { - switch_hash_this(hi, &vvar, NULL, &vval); + for (; hi; hi = hi->next) { + char *vvar = hi->name; + char *vval = hi->value; if (vvar && vval && (!prefix || (var && !strncmp((char *) vvar, var, strlen(var))))) { switch_channel_set_variable(chanb, (char *) vvar, (char *) vval); } @@ -1044,7 +1033,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_parser_destroy(switch_iv if (parser != NULL) { if (parser->hash != NULL) { - switch_core_hash_destroy(parser->hash); + switch_core_hash_destroy(&parser->hash); parser->hash = NULL; } // free the memory pool if we created it @@ -1091,7 +1080,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_parser_set_event(switch_ if (parser != NULL && digits != NULL && *digits && parser->hash != NULL) { - status = switch_core_hash_insert_dup(parser->hash, digits, data); + status = switch_core_hash_insert(parser->hash, digits, data); if (status == SWITCH_STATUS_SUCCESS) { switch_size_t len = strlen(digits); @@ -1291,13 +1280,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_ { switch_channel_t *channel; switch_caller_profile_t *caller_profile; - switch_hash_index_t *hi; - void *vval; - const void *vvar; switch_xml_t variable, variables, cdr, x_caller_profile, x_caller_extension, x_times, time_tag, x_application, x_callflow, x_inner_extension, x_apps; switch_app_log_t *app_log; - + switch_event_header_t *hi; char tmp[512]; int cdr_off = 0, v_off = 0; @@ -1330,9 +1316,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_ } } - if (((hi = switch_channel_variable_first(channel)))) { - for (; hi; hi = switch_hash_next(hi)) { - switch_hash_this(hi, &vvar, NULL, &vval); + + if ((hi = switch_channel_variable_first(channel))) { + for (; hi; hi = hi->next) { + char *vvar = hi->name; + char *vval = hi->value; if (vvar && vval) { if ((variable = switch_xml_add_child_d(variables, (char *) vvar, v_off++))) { char *data; diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index f7d017cc70..c53ba0ec4b 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -76,7 +76,7 @@ static void *SWITCH_THREAD_FUNC collect_thread_run(switch_thread_t * thread, voi { struct key_collect *collect = (struct key_collect *) obj; switch_channel_t *channel = switch_core_session_get_channel(collect->session); - char buf[10] = ""; + char buf[10] = SWITCH_BLANK_STRING; char *p, term; @@ -129,7 +129,7 @@ static void *SWITCH_THREAD_FUNC collect_thread_run(switch_thread_t * thread, voi args.buflen = sizeof(buf); switch_ivr_play_file(collect->session, NULL, collect->file, &args); } else { - switch_ivr_collect_digits_count(collect->session, buf, sizeof(buf), 1, "", &term, 0); + switch_ivr_collect_digits_count(collect->session, buf, sizeof(buf), 1, SWITCH_BLANK_STRING, &term, 0); } for (p = buf; *p; p++) { @@ -260,7 +260,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_codec_t write_codec = { 0 }; switch_frame_t write_frame = { 0 }; uint8_t fdata[1024], pass = 0; - char key[80] = "", file[512] = "", *odata, *var; + char key[80] = SWITCH_BLANK_STRING, file[512] = SWITCH_BLANK_STRING, *odata, *var; switch_call_cause_t reason = SWITCH_CAUSE_UNALLOCATED; uint8_t to = 0; char *var_val, *vars = NULL, *ringback_data = NULL; @@ -315,14 +315,19 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } if (session) { - switch_hash_index_t *hi; - void *vval; - const void *vvar; + switch_event_header_t *hi; caller_channel = switch_core_session_get_channel(session); assert(caller_channel != NULL); /* Copy all the channel variables into the event */ + if ((hi = switch_channel_variable_first(caller_channel))) { + for (; hi; hi = hi->next) { + switch_event_add_header(var_event, SWITCH_STACK_BOTTOM, (char *)hi->name, "%s", (char *) hi->value); + } + switch_channel_variable_last(caller_channel); + } + /* if ((hi = switch_channel_variable_first(caller_channel))) { for (; hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, &vvar, NULL, &vval); @@ -332,7 +337,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } switch_channel_variable_last(caller_channel); } - + */ } if (vars) { /* Parse parameters specified from the dialstring */ @@ -471,30 +476,26 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess caller_caller_profile = caller_profile_override ? caller_profile_override : switch_channel_get_caller_profile(caller_channel); new_profile = switch_caller_profile_clone(session, caller_caller_profile); - new_profile->uuid = NULL; - new_profile->chan_name = NULL; - new_profile->destination_number = chan_data; + new_profile->uuid = SWITCH_BLANK_STRING; + new_profile->chan_name = SWITCH_BLANK_STRING; + new_profile->destination_number = switch_core_strdup(new_profile->pool, chan_data); if (cid_name_override) { - new_profile->caller_id_name = cid_name_override; + new_profile->caller_id_name = switch_core_strdup(new_profile->pool, cid_name_override); } if (cid_num_override) { - new_profile->caller_id_number = cid_num_override; + new_profile->caller_id_number = switch_core_strdup(new_profile->pool, cid_num_override); } pool = NULL; } else { - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n"); - status = SWITCH_STATUS_TERM; - goto done; - } + switch_core_new_memory_pool(&pool); if (caller_profile_override) { new_profile = switch_caller_profile_dup(pool, caller_profile_override); - new_profile->destination_number = chan_data; - new_profile->uuid = NULL; - new_profile->chan_name = NULL; + new_profile->destination_number = switch_core_strdup(new_profile->pool, chan_data); + new_profile->uuid = SWITCH_BLANK_STRING; + new_profile->chan_name = SWITCH_BLANK_STRING; } else { if (!cid_name_override) { cid_name_override = "FreeSWITCH"; @@ -517,7 +518,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess peer_channels[i] = NULL; peer_sessions[i] = NULL; new_session = NULL; - + if ((reason = switch_core_session_outgoing_channel(session, chan_type, new_profile, &new_session, &pool)) != SWITCH_CAUSE_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create Outgoing Channel! cause: %s\n", switch_channel_cause2str(reason)); if (pool) { @@ -602,7 +603,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess NULL, read_codec->implementation->samples_per_second, read_codec->implementation->microseconds_per_frame / 1000, - 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, pool) == SWITCH_STATUS_SUCCESS) { + 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, + switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index 4a9ce82a31..9b6e2b4c6a 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -133,7 +133,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable const switch_endpoint_interface_t *ptr; for (ptr = new_module->module_interface->endpoint_interface; ptr; ptr = ptr->next) { if (!ptr->interface_name) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load endpoint interface from %s due to no interface name.\n", key); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load endpoint interface from %s due to no interface name.\n", key); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Endpoint '%s'\n", ptr->interface_name); switch_core_hash_insert(loadable_modules.endpoint_hash, ptr->interface_name, (const void *) ptr); @@ -147,7 +147,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable for (ptr = new_module->module_interface->codec_interface; ptr; ptr = ptr->next) { if (!ptr->interface_name) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load codec interface from %s due to no interface name.\n", key); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load codec interface from %s due to no interface name.\n", key); } else { unsigned load_interface = 1; for (impl = ptr->implementations; impl; impl = impl->next) { @@ -157,7 +157,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable } } if (!load_interface) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load codec interface %s from %s due to no iana name in an implementation.\n", ptr->interface_name, key); } else { for (impl = ptr->implementations; impl; impl = impl->next) { @@ -183,7 +183,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable for (ptr = new_module->module_interface->dialplan_interface; ptr; ptr = ptr->next) { if (!ptr->interface_name) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load dialplan interface from %s due to no interface name.\n", key); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load dialplan interface from %s due to no interface name.\n", key); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Dialplan '%s'\n", ptr->interface_name); if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD) == SWITCH_STATUS_SUCCESS) { @@ -201,7 +201,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable for (ptr = new_module->module_interface->timer_interface; ptr; ptr = ptr->next) { if (!ptr->interface_name) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load timer interface from %s due to no interface name.\n", key); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load timer interface from %s due to no interface name.\n", key); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Timer '%s'\n", ptr->interface_name); if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD) == SWITCH_STATUS_SUCCESS) { @@ -219,7 +219,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable for (ptr = new_module->module_interface->application_interface; ptr; ptr = ptr->next) { if (!ptr->interface_name) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load application interface from %s due to no interface name.\n", key); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load application interface from %s due to no interface name.\n", key); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Application '%s'\n", ptr->interface_name); if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD) == SWITCH_STATUS_SUCCESS) { @@ -239,7 +239,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable for (ptr = new_module->module_interface->api_interface; ptr; ptr = ptr->next) { if (!ptr->interface_name) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load api interface from %s due to no interface name.\n", key); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load api interface from %s due to no interface name.\n", key); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding API Function '%s'\n", ptr->interface_name); if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD) == SWITCH_STATUS_SUCCESS) { @@ -259,7 +259,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable for (ptr = new_module->module_interface->file_interface; ptr; ptr = ptr->next) { if (!ptr->interface_name) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load file interface from %s due to no interface name.\n", key); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load file interface from %s due to no interface name.\n", key); } else { int i; for (i = 0; ptr->extens[i]; i++) { @@ -280,7 +280,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable for (ptr = new_module->module_interface->speech_interface; ptr; ptr = ptr->next) { if (!ptr->interface_name) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load speech interface from %s due to no interface name.\n", key); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load speech interface from %s due to no interface name.\n", key); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Speech interface '%s'\n", ptr->interface_name); if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD) == SWITCH_STATUS_SUCCESS) { @@ -298,7 +298,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable for (ptr = new_module->module_interface->asr_interface; ptr; ptr = ptr->next) { if (!ptr->interface_name) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load asr interface from %s due to no interface name.\n", key); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load asr interface from %s due to no interface name.\n", key); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Asr interface '%s'\n", ptr->interface_name); if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD) == SWITCH_STATUS_SUCCESS) { @@ -316,7 +316,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable for (ptr = new_module->module_interface->directory_interface; ptr; ptr = ptr->next) { if (!ptr->interface_name) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load directory interface from %s due to no interface name.\n", key); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load directory interface from %s due to no interface name.\n", key); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Directory interface '%s'\n", ptr->interface_name); if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD) == SWITCH_STATUS_SUCCESS) { @@ -334,7 +334,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable for (ptr = new_module->module_interface->chat_interface; ptr; ptr = ptr->next) { if (!ptr->interface_name) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load chat interface from %s due to no interface name.\n", key); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load chat interface from %s due to no interface name.\n", key); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Chat interface '%s'\n", ptr->interface_name); if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD) == SWITCH_STATUS_SUCCESS) { @@ -352,7 +352,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable for (ptr = new_module->module_interface->say_interface; ptr; ptr = ptr->next) { if (!ptr->interface_name) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load say interface from %s due to no interface name.\n", key); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load say interface from %s due to no interface name.\n", key); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Say interface '%s'\n", ptr->interface_name); if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD) == SWITCH_STATUS_SUCCESS) { @@ -370,10 +370,10 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable for (ptr = new_module->module_interface->management_interface; ptr; ptr = ptr->next) { if (!ptr->relative_oid) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load management interface from %s due to no interface name.\n", key); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load management interface from %s due to no interface name.\n", key); } else { if (switch_core_hash_find(loadable_modules.management_hash, ptr->relative_oid)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load management interface %s. OID %s already exists\n", key, ptr->relative_oid); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, @@ -401,7 +401,6 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t 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; @@ -711,7 +710,7 @@ static switch_status_t switch_loadable_module_load_file(char *path, char *filena if (pool) { switch_core_destroy_memory_pool(&pool); } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "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); return SWITCH_STATUS_GENERR; } @@ -803,12 +802,13 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_unload_module(char *dir, switch_mutex_lock(loadable_modules.mutex); 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"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Module is not unloadable.\n"); *err = "Module is not unloadable"; status = SWITCH_STATUS_NOUNLOAD; } else { do_shutdown(module); } + switch_core_hash_delete(loadable_modules.module_hash, fname); } else { *err = "No such module!"; status = SWITCH_STATUS_FALSE; @@ -1047,8 +1047,6 @@ static void do_shutdown(switch_loadable_module_t *module) assert(module != NULL); switch_loadable_module_unprocess(module); - switch_core_hash_delete_locked(loadable_modules.module_hash, module->key, loadable_modules.mutex); - 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) { @@ -1066,10 +1064,6 @@ static void do_shutdown(switch_loadable_module_t *module) } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s has no shutdown routine\n", module->module_interface->module_name); } - - - - } SWITCH_DECLARE(void) switch_loadable_module_shutdown(void) @@ -1084,6 +1078,21 @@ SWITCH_DECLARE(void) switch_loadable_module_shutdown(void) do_shutdown(module); } + switch_core_hash_destroy(&loadable_modules.module_hash); + switch_core_hash_destroy(&loadable_modules.endpoint_hash); + switch_core_hash_destroy(&loadable_modules.codec_hash); + switch_core_hash_destroy(&loadable_modules.timer_hash); + switch_core_hash_destroy(&loadable_modules.application_hash); + switch_core_hash_destroy(&loadable_modules.api_hash); + switch_core_hash_destroy(&loadable_modules.file_hash); + switch_core_hash_destroy(&loadable_modules.speech_hash); + switch_core_hash_destroy(&loadable_modules.asr_hash); + switch_core_hash_destroy(&loadable_modules.directory_hash); + switch_core_hash_destroy(&loadable_modules.chat_hash); + switch_core_hash_destroy(&loadable_modules.say_hash); + switch_core_hash_destroy(&loadable_modules.management_hash); + switch_core_hash_destroy(&loadable_modules.dialplan_hash); + } SWITCH_DECLARE(switch_endpoint_interface_t *) switch_loadable_module_get_endpoint_interface(const char *name)