make crash protection a runtime option instead of a compile-time option

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5123 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2007-05-10 16:56:29 +00:00
parent c07224852c
commit ab34a26079
10 changed files with 130 additions and 133 deletions

View File

@ -10,10 +10,6 @@ AM_LDFLAGS = $(SWITCH_AM_LDFLAGS)
BASE = $(switch_srcdir) BASE = $(switch_srcdir)
OSARCH=`uname -s` OSARCH=`uname -s`
if CRASHPROT
AM_CFLAGS += -DCRASH_PROT
endif
.DEFAULT: .DEFAULT:
@cd src/mod && $(MAKE) $(AM_MAKEFLAGS) $@ @cd src/mod && $(MAKE) $(AM_MAKEFLAGS) $@

View File

@ -2,6 +2,8 @@
<settings> <settings>
<!--Most channels to allow at once --> <!--Most channels to allow at once -->
<param name="max-sessions" value="1000"/> <param name="max-sessions" value="1000"/>
<!--Try to catch any crashes that can be recoverable (in the context of a call)-->
<param name="crash-protection" value="false"/>
<!--RTP port range --> <!--RTP port range -->
<!--<param name="rtp-start-port" value="16384"/>--> <!--<param name="rtp-start-port" value="16384"/>-->
<!--<param name="rtp-end-port" value="32768"/>--> <!--<param name="rtp-end-port" value="32768"/>-->

View File

@ -311,9 +311,6 @@ AC_SUBST(GETLIB)
LIBCURL_CHECK_CONFIG([yes], [7.13.0], [LIBCURL_DEPS=''], [LIBCURL_DEPS='${switch_srcdir}/libs/curl/lib/libcurl.la';LIBCURL='${switch_srcdir}/libs/curl/lib/libcurl.la';LIBCURL_CPPFLAGS='-I${switch_srcdir}/libs/curl/include']) LIBCURL_CHECK_CONFIG([yes], [7.13.0], [LIBCURL_DEPS=''], [LIBCURL_DEPS='${switch_srcdir}/libs/curl/lib/libcurl.la';LIBCURL='${switch_srcdir}/libs/curl/lib/libcurl.la';LIBCURL_CPPFLAGS='-I${switch_srcdir}/libs/curl/include'])
AC_SUBST(LIBCURL_DEPS) AC_SUBST(LIBCURL_DEPS)
AC_ARG_ENABLE(crash-protection,
[ --enable-crash-protection Compile with CRASH Protection],,[enable_crash_prot="no"])
AC_ARG_ENABLE(core-odbc-support, AC_ARG_ENABLE(core-odbc-support,
[ --enable-core-odbc-support Compile with ODBC Support],,[enable_core_odbc_support="no"]) [ --enable-core-odbc-support Compile with ODBC Support],,[enable_core_odbc_support="no"])
@ -323,7 +320,6 @@ AC_ARG_ENABLE(core-libedit-support,
#AX_LIB_MYSQL([MINIMUM-VERSION]) #AX_LIB_MYSQL([MINIMUM-VERSION])
AX_LIB_MYSQL AX_LIB_MYSQL
AM_CONDITIONAL([CRASHPROT],[test "x$enable_crash_prot" != "xno"])
AM_CONDITIONAL([ADD_ODBC],[test "x$enable_core_odbc_support" != "xno"]) AM_CONDITIONAL([ADD_ODBC],[test "x$enable_core_odbc_support" != "xno"])
AM_CONDITIONAL([ADD_LIBEDIT],[test "x$enable_core_libedit_support" != "xno"]) AM_CONDITIONAL([ADD_LIBEDIT],[test "x$enable_core_libedit_support" != "xno"])
AM_CONDITIONAL([HAVE_MYSQL],[test "$found_mysql" = "yes"]) AM_CONDITIONAL([HAVE_MYSQL],[test "$found_mysql" = "yes"])

View File

@ -63,12 +63,6 @@ typedef apr_os_thread_t switch_thread_id_t;
/* #define DEBUG_ALLOC */ /* #define DEBUG_ALLOC */
#define DO_EVENTS #define DO_EVENTS
#ifdef CRASH_PROT
#define __CP "ENABLED"
#else
#define __CP "DISABLED"
#endif
#define SWITCH_EVENT_QUEUE_LEN 256 #define SWITCH_EVENT_QUEUE_LEN 256
#define SWITCH_MESSAGE_QUEUE_LEN 256 #define SWITCH_MESSAGE_QUEUE_LEN 256
#define SWITCH_SQL_QUEUE_LEN 2000 #define SWITCH_SQL_QUEUE_LEN 2000
@ -145,6 +139,22 @@ struct switch_media_bug {
struct switch_media_bug *next; struct switch_media_bug *next;
}; };
struct switch_runtime {
switch_time_t initiated;
switch_hash_t *global_vars;
switch_memory_pool_t *memory_pool;
const switch_state_handler_table_t *state_handlers[SWITCH_MAX_STATE_HANDLERS];
int state_handler_index;
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;
};
extern struct switch_runtime runtime;
void switch_core_sqldb_start(switch_memory_pool_t *pool); void switch_core_sqldb_start(switch_memory_pool_t *pool);
void switch_core_sqldb_stop(void); void switch_core_sqldb_stop(void);
void switch_core_session_init(switch_memory_pool_t *pool); void switch_core_session_init(switch_memory_pool_t *pool);

View File

@ -76,6 +76,8 @@ static inline switch_bool_t switch_is_digit_string(char *s) {
(expr && ( !strcasecmp(expr, "yes") ||\ (expr && ( !strcasecmp(expr, "yes") ||\
!strcasecmp(expr, "on") ||\ !strcasecmp(expr, "on") ||\
!strcasecmp(expr, "true") ||\ !strcasecmp(expr, "true") ||\
!strcasecmp(expr, "enabled") ||\
!strcasecmp(expr, "active") ||\
atoi(expr))) ? SWITCH_TRUE : SWITCH_FALSE atoi(expr))) ? SWITCH_TRUE : SWITCH_FALSE
/*! /*!
\brief find local ip of the box \brief find local ip of the box

View File

@ -40,19 +40,7 @@
SWITCH_DECLARE_DATA switch_directories SWITCH_GLOBAL_dirs = { 0 }; SWITCH_DECLARE_DATA switch_directories SWITCH_GLOBAL_dirs = { 0 };
/* The main runtime obj we keep this hidden for ourselves */ /* The main runtime obj we keep this hidden for ourselves */
static struct { struct switch_runtime runtime;
switch_time_t initiated;
switch_hash_t *global_vars;
switch_memory_pool_t *memory_pool;
const switch_state_handler_table_t *state_handlers[SWITCH_MAX_STATE_HANDLERS];
int state_handler_index;
FILE *console;
uint8_t running;
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
uint32_t no_new_sessions;
uint32_t shutting_down;
} runtime;
static void send_heartbeat(void) static void send_heartbeat(void)
{ {
@ -424,7 +412,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(char *console, const char **err
switch_core_set_globals(); switch_core_set_globals();
switch_core_session_init(runtime.memory_pool); switch_core_session_init(runtime.memory_pool);
switch_core_state_machine_init(runtime.memory_pool);
switch_core_hash_init(&runtime.global_vars, runtime.memory_pool); switch_core_hash_init(&runtime.global_vars, runtime.memory_pool);
@ -443,7 +430,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(char *console, const char **err
const char *var = switch_xml_attr_soft(param, "name"); const char *var = switch_xml_attr_soft(param, "name");
const char *val = switch_xml_attr_soft(param, "value"); const char *val = switch_xml_attr_soft(param, "value");
if (!strcasecmp(var, "max-sessions")) { if (!strcasecmp(var, "crash-protection")) {
runtime.crash_prot = switch_true(val);
} else if (!strcasecmp(var, "max-sessions")) {
switch_core_session_limit(atoi(val)); switch_core_session_limit(atoi(val));
} }
else if (!strcasecmp(var, "rtp-start-port")) { else if (!strcasecmp(var, "rtp-start-port")) {
@ -469,6 +458,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(char *console, const char **err
switch_xml_free(xml); switch_xml_free(xml);
} }
switch_core_state_machine_init(runtime.memory_pool);
*err = NULL; *err = NULL;
if (console) { if (console) {
@ -583,7 +574,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(char *console, cons
} }
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_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, __CP, "\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)); switch_core_session_limit(0));
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;

View File

@ -36,7 +36,7 @@
static struct { static struct {
switch_memory_pool_t *memory_pool; switch_memory_pool_t *memory_pool;
} runtime; } memory_manager;
SWITCH_DECLARE(switch_memory_pool_t *) switch_core_session_get_pool(switch_core_session_t *session) SWITCH_DECLARE(switch_memory_pool_t *) switch_core_session_get_pool(switch_core_session_t *session)
{ {
@ -68,14 +68,14 @@ SWITCH_DECLARE(void *) switch_core_session_alloc(switch_core_session_t *session,
SWITCH_DECLARE(void *) switch_core_permanent_alloc(switch_size_t memory) SWITCH_DECLARE(void *) switch_core_permanent_alloc(switch_size_t memory)
{ {
void *ptr = NULL; void *ptr = NULL;
assert(runtime.memory_pool != NULL); assert(memory_manager.memory_pool != NULL);
#ifdef DEBUG_ALLOC #ifdef DEBUG_ALLOC
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Perm Allocate %d\n", memory); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Perm Allocate %d\n", memory);
#endif #endif
if ((ptr = apr_palloc(runtime.memory_pool, memory)) != 0) { if ((ptr = apr_palloc(memory_manager.memory_pool, memory)) != 0) {
memset(ptr, 0, memory); memset(ptr, 0, memory);
} }
return ptr; return ptr;
@ -85,7 +85,7 @@ SWITCH_DECLARE(char *) switch_core_permanent_strdup(const char *todup)
{ {
char *duped = NULL; char *duped = NULL;
switch_size_t len; switch_size_t len;
assert(runtime.memory_pool != NULL); assert(memory_manager.memory_pool != NULL);
if (!todup) if (!todup)
return NULL; return NULL;
@ -96,7 +96,7 @@ SWITCH_DECLARE(char *) switch_core_permanent_strdup(const char *todup)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Perm Allocate %d\n", len); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Perm Allocate %d\n", len);
#endif #endif
if (todup && (duped = apr_palloc(runtime.memory_pool, len)) != 0) { if (todup && (duped = apr_palloc(memory_manager.memory_pool, len)) != 0) {
strncpy(duped, todup, len); strncpy(duped, todup, len);
} }
return duped; return duped;
@ -214,8 +214,8 @@ SWITCH_DECLARE(void *) switch_core_alloc(switch_memory_pool_t *pool, switch_size
switch_memory_pool_t *switch_core_memory_init(void) switch_memory_pool_t *switch_core_memory_init(void)
{ {
memset(&runtime, 0, sizeof(runtime)); memset(&memory_manager, 0, sizeof(memory_manager));
apr_pool_create(&runtime.memory_pool, NULL); apr_pool_create(&memory_manager.memory_pool, NULL);
return runtime.memory_pool; return memory_manager.memory_pool;
} }

View File

@ -41,7 +41,7 @@ static struct {
uint32_t session_count; uint32_t session_count;
uint32_t session_limit; uint32_t session_limit;
switch_size_t session_id; switch_size_t session_id;
} runtime; } session_manager;
#ifdef SWITCH_DEBUG_RWLOCKS #ifdef SWITCH_DEBUG_RWLOCKS
@ -53,8 +53,8 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(char *uuid_st
switch_core_session_t *session = NULL; switch_core_session_t *session = NULL;
if (uuid_str) { if (uuid_str) {
switch_mutex_lock(runtime.session_table_mutex); switch_mutex_lock(session_manager.session_table_mutex);
if ((session = switch_core_hash_find(runtime.session_table, uuid_str))) { if ((session = switch_core_hash_find(session_manager.session_table, uuid_str))) {
/* Acquire a read lock on the session */ /* Acquire a read lock on the session */
#ifdef SWITCH_DEBUG_RWLOCKS #ifdef SWITCH_DEBUG_RWLOCKS
if (switch_core_session_perform_read_lock(session, file, func, line) != SWITCH_STATUS_SUCCESS) { if (switch_core_session_perform_read_lock(session, file, func, line) != SWITCH_STATUS_SUCCESS) {
@ -65,7 +65,7 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(char *uuid_st
session = NULL; session = NULL;
} }
} }
switch_mutex_unlock(runtime.session_table_mutex); switch_mutex_unlock(session_manager.session_table_mutex);
} }
/* if its not NULL, now it's up to you to rwunlock this */ /* if its not NULL, now it's up to you to rwunlock this */
@ -80,8 +80,8 @@ SWITCH_DECLARE(void) switch_core_session_hupall(switch_call_cause_t cause)
switch_channel_t *channel; switch_channel_t *channel;
uint32_t loops = 0; uint32_t loops = 0;
switch_mutex_lock(runtime.session_table_mutex); switch_mutex_lock(session_manager.session_table_mutex);
for (hi = switch_hash_first(runtime.memory_pool, runtime.session_table); hi; hi = switch_hash_next(hi)) { for (hi = switch_hash_first(session_manager.memory_pool, session_manager.session_table); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val); switch_hash_this(hi, NULL, NULL, &val);
if (val) { if (val) {
session = (switch_core_session_t *) val; session = (switch_core_session_t *) val;
@ -90,13 +90,13 @@ SWITCH_DECLARE(void) switch_core_session_hupall(switch_call_cause_t cause)
switch_core_session_kill_channel(session, SWITCH_SIG_KILL); switch_core_session_kill_channel(session, SWITCH_SIG_KILL);
} }
} }
switch_mutex_unlock(runtime.session_table_mutex); switch_mutex_unlock(session_manager.session_table_mutex);
while (runtime.session_count > 0) { while (session_manager.session_count > 0) {
switch_yield(100000); switch_yield(100000);
if (++loops == 100) { if (++loops == 100) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Giving up with %d session%s remaining\n", switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Giving up with %d session%s remaining\n",
runtime.session_count, runtime.session_count == 1 ? "" : "s"); session_manager.session_count, session_manager.session_count == 1 ? "" : "s");
break; break;
} }
} }
@ -107,8 +107,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_message_send(char *uuid_str,
switch_core_session_t *session = NULL; switch_core_session_t *session = NULL;
switch_status_t status = SWITCH_STATUS_FALSE; switch_status_t status = SWITCH_STATUS_FALSE;
switch_mutex_lock(runtime.session_table_mutex); switch_mutex_lock(session_manager.session_table_mutex);
if ((session = switch_core_hash_find(runtime.session_table, uuid_str)) != 0) { if ((session = switch_core_hash_find(session_manager.session_table, uuid_str)) != 0) {
/* Acquire a read lock on the session or forget it the channel is dead */ /* Acquire a read lock on the session or forget it the channel is dead */
if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) { if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
if (switch_channel_get_state(session->channel) < CS_HANGUP) { if (switch_channel_get_state(session->channel) < CS_HANGUP) {
@ -117,7 +117,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_message_send(char *uuid_str,
switch_core_session_rwunlock(session); switch_core_session_rwunlock(session);
} }
} }
switch_mutex_unlock(runtime.session_table_mutex); switch_mutex_unlock(session_manager.session_table_mutex);
return status; return status;
} }
@ -127,8 +127,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_event_send(char *uuid_str, s
switch_core_session_t *session = NULL; switch_core_session_t *session = NULL;
switch_status_t status = SWITCH_STATUS_FALSE; switch_status_t status = SWITCH_STATUS_FALSE;
switch_mutex_lock(runtime.session_table_mutex); switch_mutex_lock(session_manager.session_table_mutex);
if ((session = switch_core_hash_find(runtime.session_table, uuid_str)) != 0) { if ((session = switch_core_hash_find(session_manager.session_table, uuid_str)) != 0) {
/* Acquire a read lock on the session or forget it the channel is dead */ /* Acquire a read lock on the session or forget it the channel is dead */
if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) { if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
if (switch_channel_get_state(session->channel) < CS_HANGUP) { if (switch_channel_get_state(session->channel) < CS_HANGUP) {
@ -137,7 +137,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_event_send(char *uuid_str, s
switch_core_session_rwunlock(session); switch_core_session_rwunlock(session);
} }
} }
switch_mutex_unlock(runtime.session_table_mutex); switch_mutex_unlock(session_manager.session_table_mutex);
return status; return status;
} }
@ -662,12 +662,12 @@ SWITCH_DECLARE(void) switch_core_session_destroy(switch_core_session_t **session
switch_scheduler_del_task_group((*session)->uuid_str); switch_scheduler_del_task_group((*session)->uuid_str);
switch_mutex_lock(runtime.session_table_mutex); switch_mutex_lock(session_manager.session_table_mutex);
switch_core_hash_delete(runtime.session_table, (*session)->uuid_str); switch_core_hash_delete(session_manager.session_table, (*session)->uuid_str);
if (runtime.session_count) { if (session_manager.session_count) {
runtime.session_count--; session_manager.session_count--;
} }
switch_mutex_unlock(runtime.session_table_mutex); switch_mutex_unlock(session_manager.session_table_mutex);
if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DESTROY) == SWITCH_STATUS_SUCCESS) { if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DESTROY) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data((*session)->channel, event); switch_channel_event_set_data((*session)->channel, event);
@ -750,11 +750,11 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request(const switch
assert(endpoint_interface != NULL); assert(endpoint_interface != NULL);
switch_mutex_lock(runtime.session_table_mutex); switch_mutex_lock(session_manager.session_table_mutex);
count = runtime.session_count; count = session_manager.session_count;
switch_mutex_unlock(runtime.session_table_mutex); switch_mutex_unlock(session_manager.session_table_mutex);
if ((count + 1) > runtime.session_limit) { if ((count + 1) > session_manager.session_limit) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Limit!\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Limit!\n");
return NULL; return NULL;
} }
@ -812,23 +812,23 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request(const switch
switch_thread_rwlock_create(&session->rwlock, session->pool); switch_thread_rwlock_create(&session->rwlock, session->pool);
snprintf(session->name, sizeof(session->name), "%"SWITCH_SIZE_T_FMT, session->id); snprintf(session->name, sizeof(session->name), "%"SWITCH_SIZE_T_FMT, session->id);
switch_mutex_lock(runtime.session_table_mutex); switch_mutex_lock(session_manager.session_table_mutex);
session->id = runtime.session_id++; session->id = session_manager.session_id++;
switch_core_hash_insert(runtime.session_table, session->uuid_str, session); switch_core_hash_insert(session_manager.session_table, session->uuid_str, session);
runtime.session_count++; session_manager.session_count++;
switch_mutex_unlock(runtime.session_table_mutex); switch_mutex_unlock(session_manager.session_table_mutex);
return session; return session;
} }
SWITCH_DECLARE(uint32_t) switch_core_session_count(void) SWITCH_DECLARE(uint32_t) switch_core_session_count(void)
{ {
return runtime.session_count; return session_manager.session_count;
} }
SWITCH_DECLARE(switch_size_t) switch_core_session_id(void) SWITCH_DECLARE(switch_size_t) switch_core_session_id(void)
{ {
return runtime.session_id; return session_manager.session_id;
} }
@ -867,21 +867,21 @@ SWITCH_DECLARE(char *) switch_core_session_get_uuid(switch_core_session_t *sessi
SWITCH_DECLARE(uint32_t) switch_core_session_limit(uint32_t new_limit) SWITCH_DECLARE(uint32_t) switch_core_session_limit(uint32_t new_limit)
{ {
if (new_limit) { if (new_limit) {
runtime.session_limit = new_limit; session_manager.session_limit = new_limit;
} }
return runtime.session_limit; return session_manager.session_limit;
} }
void switch_core_session_init(switch_memory_pool_t *pool) void switch_core_session_init(switch_memory_pool_t *pool)
{ {
memset(&runtime, 0, sizeof(runtime)); memset(&session_manager, 0, sizeof(session_manager));
runtime.session_limit = 1000; session_manager.session_limit = 1000;
runtime.session_id = 1; session_manager.session_id = 1;
runtime.memory_pool = pool; session_manager.memory_pool = pool;
switch_core_hash_init(&runtime.session_table, runtime.memory_pool); switch_core_hash_init(&session_manager.session_table, session_manager.memory_pool);
switch_mutex_init(&runtime.session_table_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); switch_mutex_init(&session_manager.session_table_mutex, SWITCH_MUTEX_NESTED, session_manager.memory_pool);
} }

View File

@ -40,7 +40,7 @@ static struct {
switch_queue_t *sql_queue; switch_queue_t *sql_queue;
switch_memory_pool_t *memory_pool; switch_memory_pool_t *memory_pool;
int thread_running; int thread_running;
} runtime; } sql_manager;
static switch_status_t switch_core_db_persistant_execute_trans(switch_core_db_t *db, char *sql, uint32_t retries) static switch_status_t switch_core_db_persistant_execute_trans(switch_core_db_t *db, char *sql, uint32_t retries)
{ {
@ -157,14 +157,14 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t * thread,
char *sql; char *sql;
switch_size_t newlen; switch_size_t newlen;
if (!runtime.event_db) { if (!sql_manager.event_db) {
runtime.event_db = switch_core_db_handle(); sql_manager.event_db = switch_core_db_handle();
} }
runtime.thread_running = 1; sql_manager.thread_running = 1;
for (;;) { for (;;) {
if (switch_queue_trypop(runtime.sql_queue, &pop) == SWITCH_STATUS_SUCCESS) { if (switch_queue_trypop(sql_manager.sql_queue, &pop) == SWITCH_STATUS_SUCCESS) {
sql = (char *) pop; sql = (char *) pop;
if (sql) { if (sql) {
@ -199,7 +199,7 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t * thread,
if (trans && ((itterations == target) || nothing_in_queue)) { if (trans && ((itterations == target) || nothing_in_queue)) {
if (switch_core_db_persistant_execute_trans(runtime.event_db, sqlbuf, 1000) != SWITCH_STATUS_SUCCESS) { if (switch_core_db_persistant_execute_trans(sql_manager.event_db, sqlbuf, 1000) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread unable to commit transaction, records lost!\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread unable to commit transaction, records lost!\n");
} }
itterations = 0; itterations = 0;
@ -228,7 +228,7 @@ static void core_event_handler(switch_event_t *event)
sql = switch_mprintf("insert into tasks values('%q','%q','%q','%q')", sql = switch_mprintf("insert into tasks values('%q','%q','%q','%q')",
switch_event_get_header(event, "task-id"), switch_event_get_header(event, "task-id"),
switch_event_get_header(event, "task-desc"), switch_event_get_header(event, "task-desc"),
switch_event_get_header(event, "task-group"), switch_event_get_header(event, "task-runtime") switch_event_get_header(event, "task-group"), switch_event_get_header(event, "task-sql_manager")
); );
break; break;
case SWITCH_EVENT_DEL_SCHEDULE: case SWITCH_EVENT_DEL_SCHEDULE:
@ -236,8 +236,8 @@ static void core_event_handler(switch_event_t *event)
sql = switch_mprintf("delete from tasks where task_id=%q", switch_event_get_header(event, "task-id")); sql = switch_mprintf("delete from tasks where task_id=%q", switch_event_get_header(event, "task-id"));
break; break;
case SWITCH_EVENT_RE_SCHEDULE: case SWITCH_EVENT_RE_SCHEDULE:
sql = switch_mprintf("update tasks set task_runtime='%q' where task_id=%q", sql = switch_mprintf("update tasks set task_sql_manager='%q' where task_id=%q",
switch_event_get_header(event, "task-runtime"), switch_event_get_header(event, "task-id")); switch_event_get_header(event, "task-sql_manager"), switch_event_get_header(event, "task-id"));
break; break;
case SWITCH_EVENT_CHANNEL_DESTROY: case SWITCH_EVENT_CHANNEL_DESTROY:
sql = switch_mprintf("delete from channels where uuid='%q'", switch_event_get_header(event, "unique-id")); sql = switch_mprintf("delete from channels where uuid='%q'", switch_event_get_header(event, "unique-id"));
@ -334,7 +334,7 @@ static void core_event_handler(switch_event_t *event)
} }
if (sql) { if (sql) {
switch_queue_push(runtime.sql_queue, sql); switch_queue_push(sql_manager.sql_queue, sql);
sql = NULL; sql = NULL;
} }
} }
@ -345,10 +345,10 @@ void switch_core_sqldb_start(switch_memory_pool_t *pool)
switch_thread_t *thread; switch_thread_t *thread;
switch_threadattr_t *thd_attr;; switch_threadattr_t *thd_attr;;
runtime.memory_pool = pool; sql_manager.memory_pool = pool;
/* Activate SQL database */ /* Activate SQL database */
if ((runtime.db = switch_core_db_handle()) == 0) { if ((sql_manager.db = switch_core_db_handle()) == 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n");
} else { } else {
char create_channels_sql[] = char create_channels_sql[] =
@ -382,43 +382,43 @@ void switch_core_sqldb_start(switch_memory_pool_t *pool)
char create_tasks_sql[] = char create_tasks_sql[] =
"CREATE TABLE tasks (\n" "CREATE TABLE tasks (\n"
" task_id INTEGER(4),\n" " task_id INTEGER(4),\n"
" task_desc VARCHAR(255),\n" " task_group VARCHAR(255),\n" " task_runtime INTEGER(8)\n" ");\n"; " task_desc VARCHAR(255),\n" " task_group VARCHAR(255),\n" " task_sql_manager INTEGER(8)\n" ");\n";
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening DB\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening DB\n");
switch_core_db_exec(runtime.db, "drop table channels", NULL, NULL, NULL); switch_core_db_exec(sql_manager.db, "drop table channels", NULL, NULL, NULL);
switch_core_db_exec(runtime.db, "drop table calls", NULL, NULL, NULL); switch_core_db_exec(sql_manager.db, "drop table calls", NULL, NULL, NULL);
switch_core_db_exec(runtime.db, "drop table interfaces", NULL, NULL, NULL); switch_core_db_exec(sql_manager.db, "drop table interfaces", NULL, NULL, NULL);
switch_core_db_exec(runtime.db, "drop table tasks", NULL, NULL, NULL); switch_core_db_exec(sql_manager.db, "drop table tasks", NULL, NULL, NULL);
switch_core_db_exec(runtime.db, create_channels_sql, NULL, NULL, NULL); switch_core_db_exec(sql_manager.db, create_channels_sql, NULL, NULL, NULL);
switch_core_db_exec(runtime.db, create_calls_sql, NULL, NULL, NULL); switch_core_db_exec(sql_manager.db, create_calls_sql, NULL, NULL, NULL);
switch_core_db_exec(runtime.db, create_interfaces_sql, NULL, NULL, NULL); switch_core_db_exec(sql_manager.db, create_interfaces_sql, NULL, NULL, NULL);
switch_core_db_exec(runtime.db, create_tasks_sql, NULL, NULL, NULL); switch_core_db_exec(sql_manager.db, create_tasks_sql, NULL, NULL, NULL);
if (switch_event_bind("core_db", SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY, core_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { if (switch_event_bind("core_db", SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY, core_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind event handler!\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind event handler!\n");
} }
} }
switch_queue_create(&runtime.sql_queue, SWITCH_SQL_QUEUE_LEN, runtime.memory_pool); switch_queue_create(&sql_manager.sql_queue, SWITCH_SQL_QUEUE_LEN, sql_manager.memory_pool);
switch_threadattr_create(&thd_attr, runtime.memory_pool); switch_threadattr_create(&thd_attr, sql_manager.memory_pool);
switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_detach_set(thd_attr, 1);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
switch_thread_create(&thread, thd_attr, switch_core_sql_thread, NULL, runtime.memory_pool); switch_thread_create(&thread, thd_attr, switch_core_sql_thread, NULL, sql_manager.memory_pool);
while (!runtime.thread_running) { while (!sql_manager.thread_running) {
switch_yield(10000); switch_yield(10000);
} }
} }
void switch_core_sqldb_stop(void) void switch_core_sqldb_stop(void)
{ {
switch_queue_push(runtime.sql_queue, NULL); switch_queue_push(sql_manager.sql_queue, NULL);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Waiting for unfinished SQL transactions\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Waiting for unfinished SQL transactions\n");
while (switch_queue_size(runtime.sql_queue) > 0) { while (switch_queue_size(sql_manager.sql_queue) > 0) {
switch_yield(10000); switch_yield(10000);
} }
switch_core_db_close(runtime.db); switch_core_db_close(sql_manager.db);
switch_core_db_close(runtime.event_db); switch_core_db_close(sql_manager.event_db);
} }

View File

@ -204,9 +204,7 @@ static void switch_core_standard_on_hibernate(switch_core_session_t *session)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Standard HIBERNATE\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Standard HIBERNATE\n");
} }
static switch_hash_t *stack_table = NULL;
#ifdef CRASH_PROT
static switch_hash_t *stack_table;
#if defined (__GNUC__) && defined (LINUX) #if defined (__GNUC__) && defined (LINUX)
#include <execinfo.h> #include <execinfo.h>
#include <stdio.h> #include <stdio.h>
@ -254,14 +252,13 @@ static void handle_fatality(int sig)
abort(); abort();
} }
} }
#endif
void switch_core_state_machine_init(switch_memory_pool_t *pool) void switch_core_state_machine_init(switch_memory_pool_t *pool)
{ {
(void)0; if (runtime.crash_prot) {
#ifdef CRASH_PROT switch_core_hash_init(&stack_table, pool);
switch_core_hash_init(&stack_table, pool); }
#endif
} }
SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
@ -270,31 +267,33 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
const switch_endpoint_interface_t *endpoint_interface; const switch_endpoint_interface_t *endpoint_interface;
const switch_state_handler_table_t *driver_state_handler = NULL; const switch_state_handler_table_t *driver_state_handler = NULL;
const switch_state_handler_table_t *application_state_handler = NULL; const switch_state_handler_table_t *application_state_handler = NULL;
switch_thread_id_t thread_id;
#ifdef CRASH_PROT
switch_thread_id_t thread_id = switch_thread_self();
jmp_buf env; jmp_buf env;
int sig; int sig;
signal(SIGSEGV, handle_fatality); if (runtime.crash_prot) {
signal(SIGFPE, handle_fatality); thread_id = switch_thread_self();
signal(SIGSEGV, handle_fatality);
signal(SIGFPE, handle_fatality);
#ifndef WIN32 #ifndef WIN32
signal(SIGBUS, handle_fatality); signal(SIGBUS, handle_fatality);
#endif #endif
if ((sig = setjmp(env)) != 0) { if ((sig = setjmp(env)) != 0) {
switch_event_t *event; switch_event_t *event;
if (switch_event_create(&event, SWITCH_EVENT_SESSION_CRASH) == SWITCH_STATUS_SUCCESS) { if (switch_event_create(&event, SWITCH_EVENT_SESSION_CRASH) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(session->channel, event); switch_channel_event_set_data(session->channel, event);
switch_event_fire(&event); switch_event_fire(&event);
}
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);
} }
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);
} }
#endif
/* /*
Life of the channel. you have channel and pool in your session Life of the channel. you have channel and pool in your session
everywhere you go you use the session to malloc with everywhere you go you use the session to malloc with
@ -646,9 +645,9 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
done: done:
switch_mutex_unlock(session->mutex); switch_mutex_unlock(session->mutex);
#ifdef CRASH_PROT if (runtime.crash_prot) {
apr_hash_set(stack_table, &thread_id, sizeof(thread_id), NULL); apr_hash_set(stack_table, &thread_id, sizeof(thread_id), NULL);
#endif }
session->thread_running = 0; session->thread_running = 0;
} }