提交 b5a19020 authored 作者: Anthony Minessale's avatar Anthony Minessale

add session counter and make all sessions hang up elegantly on shutdown

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@1788 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 ecb7c089
<?xml version="1.0"?> <?xml version="1.0"?>
<document type="freeswitch/xml"> <document type="freeswitch/xml">
<section name="configuration" description="Various Configuration"> <section name="configuration" description="Various Configuration">
<configuration name="modules.conf" description="Modules">
<settings>
<!--Most channels to allow at once -->
<param name="max-sessions" value="1000"/>
</settings>
</configuration>
<configuration name="modules.conf" description="Modules"> <configuration name="modules.conf" description="Modules">
<modules> <modules>
<!-- Loggers (I'd load these first) --> <!-- Loggers (I'd load these first) -->
......
...@@ -116,6 +116,13 @@ struct switch_core_runtime; ...@@ -116,6 +116,13 @@ struct switch_core_runtime;
*/ */
SWITCH_DECLARE(switch_status_t) switch_core_init(char *console, const char **err); SWITCH_DECLARE(switch_status_t) switch_core_init(char *console, const char **err);
/*!
\brief Set/Get Session Limit
\param new new value (if > 0)
\return the current session limit
*/
SWITCH_DECLARE(uint32_t) switch_core_session_limit(uint32_t new);
/*! /*!
\brief Destroy the core \brief Destroy the core
\note to be called at application shutdown \note to be called at application shutdown
...@@ -309,6 +316,11 @@ SWITCH_DECLARE(char *) switch_core_session_get_uuid(switch_core_session_t *sessi ...@@ -309,6 +316,11 @@ SWITCH_DECLARE(char *) switch_core_session_get_uuid(switch_core_session_t *sessi
*/ */
SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(char *uuid_str); SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(char *uuid_str);
/*!
\brief Hangup All Sessions
*/
SWITCH_DECLARE(void) switch_core_session_hupall(void);
/*! /*!
\brief Send a message to another session using it's uuid \brief Send a message to another session using it's uuid
\param uuid_str the unique id of the session you want to send a message to \param uuid_str the unique id of the session you want to send a message to
......
...@@ -619,7 +619,8 @@ typedef enum { ...@@ -619,7 +619,8 @@ typedef enum {
SWITCH_CAUSE_MANDATORY_IE_LENGTH_ERROR = 103, SWITCH_CAUSE_MANDATORY_IE_LENGTH_ERROR = 103,
SWITCH_CAUSE_PROTOCOL_ERROR = 111, SWITCH_CAUSE_PROTOCOL_ERROR = 111,
SWITCH_CAUSE_INTERWORKING = 127, SWITCH_CAUSE_INTERWORKING = 127,
SWITCH_CAUSE_CRASH = 500 SWITCH_CAUSE_CRASH = 500,
SWITCH_CAUSE_SYSTEM_SHUTDOWN = 501
} switch_call_cause_t; } switch_call_cause_t;
......
...@@ -188,7 +188,7 @@ int main(int argc, char *argv[]) ...@@ -188,7 +188,7 @@ int main(int argc, char *argv[])
#define __CP "DISABLED" #define __CP "DISABLED"
#endif #endif
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "freeswitch Version %s Started. Crash Protection [%s]\n\n", SWITCH_VERSION_FULL, __CP); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "freeswitch Version %s Started. Crash Protection [%s] Max Sessions[%u]\n\n", SWITCH_VERSION_FULL, __CP, switch_core_session_limit(0));
snprintf(path, sizeof(path), "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, pfile); snprintf(path, sizeof(path), "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, pfile);
if (bg) { if (bg) {
...@@ -217,6 +217,8 @@ int main(int argc, char *argv[]) ...@@ -217,6 +217,8 @@ int main(int argc, char *argv[])
switch_event_fire(&event); switch_event_fire(&event);
} }
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "End existing sessions\n");
switch_core_session_hupall();
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clean up modules.\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clean up modules.\n");
switch_loadable_module_shutdown(); switch_loadable_module_shutdown();
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Tearing down environment.\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Tearing down environment.\n");
......
...@@ -83,6 +83,7 @@ static struct switch_cause_table CAUSE_CHART[] = { ...@@ -83,6 +83,7 @@ static struct switch_cause_table CAUSE_CHART[] = {
{ "PROTOCOL_ERROR", SWITCH_CAUSE_PROTOCOL_ERROR }, { "PROTOCOL_ERROR", SWITCH_CAUSE_PROTOCOL_ERROR },
{ "INTERWORKING", SWITCH_CAUSE_INTERWORKING }, { "INTERWORKING", SWITCH_CAUSE_INTERWORKING },
{ "CRASH", SWITCH_CAUSE_CRASH }, { "CRASH", SWITCH_CAUSE_CRASH },
{ "SYSTEM_SHUTDOWN", SWITCH_CAUSE_SYSTEM_SHUTDOWN },
{ NULL, 0 } { NULL, 0 }
}; };
......
...@@ -85,6 +85,7 @@ struct switch_core_runtime { ...@@ -85,6 +85,7 @@ struct switch_core_runtime {
uint32_t session_id; uint32_t session_id;
apr_pool_t *memory_pool; apr_pool_t *memory_pool;
switch_hash_t *session_table; switch_hash_t *session_table;
switch_mutex_t *session_table_mutex;
#ifdef CRASH_PROT #ifdef CRASH_PROT
switch_hash_t *stack_table; switch_hash_t *stack_table;
#endif #endif
...@@ -93,6 +94,8 @@ struct switch_core_runtime { ...@@ -93,6 +94,8 @@ struct switch_core_runtime {
const switch_state_handler_table_t *state_handlers[SWITCH_MAX_STATE_HANDLERS]; const switch_state_handler_table_t *state_handlers[SWITCH_MAX_STATE_HANDLERS];
int state_handler_index; int state_handler_index;
FILE *console; FILE *console;
uint32_t session_count;
uint32_t session_limit;
switch_queue_t *sql_queue; switch_queue_t *sql_queue;
}; };
...@@ -246,6 +249,8 @@ SWITCH_DECLARE(void) switch_core_session_rwunlock(switch_core_session_t *session ...@@ -246,6 +249,8 @@ SWITCH_DECLARE(void) switch_core_session_rwunlock(switch_core_session_t *session
SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(char *uuid_str) SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(char *uuid_str)
{ {
switch_core_session_t *session; switch_core_session_t *session;
switch_mutex_lock(runtime.session_table_mutex);
if ((session = switch_core_hash_find(runtime.session_table, uuid_str))) { if ((session = switch_core_hash_find(runtime.session_table, uuid_str))) {
/* Acquire a read lock on the session */ /* Acquire a read lock on the session */
if (switch_thread_rwlock_tryrdlock(session->rwlock) != SWITCH_STATUS_SUCCESS) { if (switch_thread_rwlock_tryrdlock(session->rwlock) != SWITCH_STATUS_SUCCESS) {
...@@ -253,16 +258,41 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(char *uuid_st ...@@ -253,16 +258,41 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(char *uuid_st
session = NULL; session = NULL;
} }
} }
switch_mutex_unlock(runtime.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 */
return session; return session;
} }
SWITCH_DECLARE(void) switch_core_session_hupall(void)
{
switch_hash_index_t *hi;
void *val;
switch_core_session_t *session;
switch_channel_t *channel;
switch_mutex_lock(runtime.session_table_mutex);
for (hi = switch_hash_first(runtime.memory_pool, runtime.session_table); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
if (val) {
session = (switch_core_session_t *) val;
channel = switch_core_session_get_channel(session);
switch_channel_hangup(channel, SWITCH_CAUSE_SYSTEM_SHUTDOWN);
}
}
switch_mutex_unlock(runtime.session_table_mutex);
while(runtime.session_count) {
switch_yield(1000);
}
}
SWITCH_DECLARE(switch_status_t) switch_core_session_message_send(char *uuid_str, switch_core_session_message_t *message) SWITCH_DECLARE(switch_status_t) switch_core_session_message_send(char *uuid_str, switch_core_session_message_t *message)
{ {
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);
if ((session = switch_core_hash_find(runtime.session_table, uuid_str)) != 0) { if ((session = switch_core_hash_find(runtime.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_thread_rwlock_tryrdlock(session->rwlock) == SWITCH_STATUS_SUCCESS) { if (switch_thread_rwlock_tryrdlock(session->rwlock) == SWITCH_STATUS_SUCCESS) {
...@@ -272,6 +302,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_message_send(char *uuid_str, ...@@ -272,6 +302,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_message_send(char *uuid_str,
switch_thread_rwlock_unlock(session->rwlock); switch_thread_rwlock_unlock(session->rwlock);
} }
} }
switch_mutex_unlock(runtime.session_table_mutex);
return status; return status;
} }
...@@ -281,6 +312,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_event_send(char *uuid_str, s ...@@ -281,6 +312,7 @@ 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);
if ((session = switch_core_hash_find(runtime.session_table, uuid_str)) != 0) { if ((session = switch_core_hash_find(runtime.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_thread_rwlock_tryrdlock(session->rwlock) == SWITCH_STATUS_SUCCESS) { if (switch_thread_rwlock_tryrdlock(session->rwlock) == SWITCH_STATUS_SUCCESS) {
...@@ -290,6 +322,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_event_send(char *uuid_str, s ...@@ -290,6 +322,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_event_send(char *uuid_str, s
switch_thread_rwlock_unlock(session->rwlock); switch_thread_rwlock_unlock(session->rwlock);
} }
} }
switch_mutex_unlock(runtime.session_table_mutex);
return status; return status;
} }
...@@ -2344,6 +2377,9 @@ SWITCH_DECLARE(void) switch_core_session_destroy(switch_core_session_t **session ...@@ -2344,6 +2377,9 @@ SWITCH_DECLARE(void) switch_core_session_destroy(switch_core_session_t **session
apr_pool_destroy(pool); apr_pool_destroy(pool);
pool = NULL; pool = NULL;
switch_mutex_lock(runtime.session_table_mutex);
runtime.session_count--;
switch_mutex_unlock(runtime.session_table_mutex);
} }
SWITCH_DECLARE(switch_status_t) switch_core_hash_init(switch_hash_t **hash, switch_memory_pool_t *pool) SWITCH_DECLARE(switch_status_t) switch_core_hash_init(switch_hash_t **hash, switch_memory_pool_t *pool)
...@@ -2434,18 +2470,21 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread(switch_thread_t *thre ...@@ -2434,18 +2470,21 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread(switch_thread_t *thre
{ {
switch_core_session_t *session = obj; switch_core_session_t *session = obj;
session->thread = thread; session->thread = thread;
session->id = runtime.session_id++;
snprintf(session->name, sizeof(session->name), "%u", session->id); snprintf(session->name, sizeof(session->name), "%u", session->id);
switch_mutex_lock(runtime.session_table_mutex);
session->id = runtime.session_id++;
switch_core_hash_insert(runtime.session_table, session->uuid_str, session); switch_core_hash_insert(runtime.session_table, session->uuid_str, session);
switch_mutex_unlock(runtime.session_table_mutex);
switch_core_session_run(session); switch_core_session_run(session);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Session %u (%s) Locked, Waiting on external entities\n", session->id, switch_channel_get_name(session->channel)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Session %u (%s) Locked, Waiting on external entities\n", session->id, switch_channel_get_name(session->channel));
switch_core_session_write_lock(session); switch_core_session_write_lock(session);
switch_core_session_rwunlock(session); switch_core_session_rwunlock(session);
switch_mutex_lock(runtime.session_table_mutex);
switch_core_hash_delete(runtime.session_table, session->uuid_str); switch_core_hash_delete(runtime.session_table, session->uuid_str);
switch_mutex_unlock(runtime.session_table_mutex);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Session %u (%s) Ended\n", session->id, switch_channel_get_name(session->channel)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Session %u (%s) Ended\n", session->id, switch_channel_get_name(session->channel));
switch_core_session_destroy(&session); switch_core_session_destroy(&session);
return NULL; return NULL;
...@@ -2503,9 +2542,19 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request(const switch ...@@ -2503,9 +2542,19 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request(const switch
switch_memory_pool_t *usepool; switch_memory_pool_t *usepool;
switch_core_session_t *session; switch_core_session_t *session;
switch_uuid_t uuid; switch_uuid_t uuid;
uint32_t count = 0;
assert(endpoint_interface != NULL); assert(endpoint_interface != NULL);
switch_mutex_lock(runtime.session_table_mutex);
count = runtime.session_count;
switch_mutex_unlock(runtime.session_table_mutex);
if ((count + 1) > runtime.session_limit) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Limit!\n");
return NULL;
}
if (pool) { if (pool) {
usepool = pool; usepool = pool;
} else if (switch_core_new_memory_pool(&usepool) != SWITCH_STATUS_SUCCESS) { } else if (switch_core_new_memory_pool(&usepool) != SWITCH_STATUS_SUCCESS) {
...@@ -2551,6 +2600,9 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request(const switch ...@@ -2551,6 +2600,9 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request(const switch
switch_thread_cond_create(&session->cond, session->pool); switch_thread_cond_create(&session->cond, session->pool);
switch_thread_rwlock_create(&session->rwlock, session->pool); switch_thread_rwlock_create(&session->rwlock, session->pool);
switch_mutex_lock(runtime.session_table_mutex);
runtime.session_count++;
switch_mutex_unlock(runtime.session_table_mutex);
return session; return session;
} }
...@@ -2806,10 +2858,22 @@ SWITCH_DECLARE(void) switch_core_set_globals(void) ...@@ -2806,10 +2858,22 @@ SWITCH_DECLARE(void) switch_core_set_globals(void)
#endif #endif
} }
SWITCH_DECLARE(uint32_t) switch_core_session_limit(uint32_t new)
{
if (new) {
runtime.session_limit = new;
}
return runtime.session_limit;
}
SWITCH_DECLARE(switch_status_t) switch_core_init(char *console, const char **err) SWITCH_DECLARE(switch_status_t) switch_core_init(char *console, const char **err)
{ {
memset(&runtime, 0, sizeof(runtime)); memset(&runtime, 0, sizeof(runtime));
runtime.session_limit = 1000;
switch_xml_t xml = NULL, cfg = NULL;
switch_core_set_globals(); switch_core_set_globals();
/* INIT APR and Create the pool context */ /* INIT APR and Create the pool context */
...@@ -2830,6 +2894,23 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(char *console, const char **err ...@@ -2830,6 +2894,23 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(char *console, const char **err
return SWITCH_STATUS_MEMERR; return SWITCH_STATUS_MEMERR;
} }
if ((xml = switch_xml_open_cfg("switch.conf", &cfg, NULL))) {
switch_xml_t settings, param;
if ((settings = switch_xml_child(cfg, "settings"))) {
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
if (!strcasecmp(var, "max-sessions")) {
runtime.session_limit = atoi(val);
}
}
}
switch_xml_free(xml);
}
*err = NULL; *err = NULL;
if(console) { if(console) {
...@@ -2909,6 +2990,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(char *console, const char **err ...@@ -2909,6 +2990,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(char *console, const char **err
runtime.session_id = 1; runtime.session_id = 1;
switch_core_hash_init(&runtime.session_table, runtime.memory_pool); switch_core_hash_init(&runtime.session_table, runtime.memory_pool);
switch_mutex_init(&runtime.session_table_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
#ifdef CRASH_PROT #ifdef CRASH_PROT
switch_core_hash_init(&runtime.stack_table, runtime.memory_pool); switch_core_hash_init(&runtime.stack_table, runtime.memory_pool);
#endif #endif
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论