diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 2cfdee869d..44b653d9ce 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -2380,11 +2380,6 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_ int32_t sps = 0; - if (use_uuid && switch_core_hash_find(session_manager.session_table, use_uuid)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Duplicate UUID!\n"); - return NULL; - } - if (direction == SWITCH_CALL_DIRECTION_INBOUND && !switch_core_ready_inbound()) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The system cannot create any inbound sessions at this time.\n"); return NULL; @@ -2406,6 +2401,15 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_ PROTECT_INTERFACE(endpoint_interface); + switch_mutex_lock(runtime.session_hash_mutex); + if (use_uuid && switch_core_hash_find(session_manager.session_table, use_uuid)) { + switch_mutex_unlock(runtime.session_hash_mutex); + UNPROTECT_INTERFACE(endpoint_interface); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Duplicate UUID!\n"); + + return NULL; + } + if (!(originate_flags & SOF_NO_LIMITS)) { switch_mutex_lock(runtime.throttle_mutex); count = session_manager.session_count; @@ -2413,12 +2417,14 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_ switch_mutex_unlock(runtime.throttle_mutex); if (sps <= 0) { + switch_mutex_unlock(runtime.session_hash_mutex); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Throttle Error! %d\n", session_manager.session_count); UNPROTECT_INTERFACE(endpoint_interface); return NULL; } if ((count + 1) > session_manager.session_limit) { + switch_mutex_unlock(runtime.session_hash_mutex); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Limit! %d\n", session_manager.session_limit); UNPROTECT_INTERFACE(endpoint_interface); return NULL; @@ -2490,7 +2496,6 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_ switch_queue_create(&session->private_event_queue, SWITCH_EVENT_QUEUE_LEN, session->pool); switch_queue_create(&session->private_event_queue_pri, SWITCH_EVENT_QUEUE_LEN, session->pool); - switch_mutex_lock(runtime.session_hash_mutex); switch_core_hash_insert(session_manager.session_table, session->uuid_str, session); session->id = session_manager.session_id++; session_manager.session_count++; diff --git a/src/switch_time.c b/src/switch_time.c index 44c1edbcce..445e698f9b 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -1243,15 +1243,17 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) if (runtime.sps <= 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Rate of %d!\n", runtime.sps_total); } + + /* These two mutexes must be held in exact order: session_hash_mutex and then throttle_mutex. See switch_core_session_request_uuid() */ + switch_mutex_lock(runtime.session_hash_mutex); switch_mutex_lock(runtime.throttle_mutex); runtime.sps_last = runtime.sps_total - runtime.sps; if (sps_interval_ticks >= 300) { runtime.sps_peak_fivemin = 0; sps_interval_ticks = 0; - switch_mutex_lock(runtime.session_hash_mutex); + /* This line is protected by runtime.session_hash_mutex */ runtime.sessions_peak_fivemin = session_manager.session_count; - switch_mutex_unlock(runtime.session_hash_mutex); } sps_interval_ticks++; @@ -1265,6 +1267,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) } runtime.sps = runtime.sps_total; switch_mutex_unlock(runtime.throttle_mutex); + switch_mutex_unlock(runtime.session_hash_mutex); tick = 0; } #ifndef DISABLE_1MS_COND