提交 cfeb6aaf authored 作者: William King's avatar William King

Since there isn't neutral ground, on the rtmp state callback we actually have to…

Since there isn't neutral ground, on the rtmp state callback we actually have to force the write lock of the session, but we only need a try lock on removing the session from the rsession->session_hash. This removes a deadlock caused when we had to enforce with locks that the rsession couldn't be destroyed if the FS session was in the middle of a hangup.
上级 f24d1cde
...@@ -284,12 +284,17 @@ switch_status_t rtmp_on_hangup(switch_core_session_t *session) ...@@ -284,12 +284,17 @@ switch_status_t rtmp_on_hangup(switch_core_session_t *session)
rtmp_notify_call_state(session); rtmp_notify_call_state(session);
rtmp_send_onhangup(session); rtmp_send_onhangup(session);
switch_core_hash_delete_wrlock(rsession->session_hash, switch_core_session_get_uuid(session), rsession->session_rwlock); /*
* If the session_rwlock is already locked, then there is a larger possibility that the rsession
* is looping through because the rsession is trying to hang them up. If that is the case, then there
* is really no reason to foce this hash_delete. Just timeout, and let the rsession handle the final cleanup
* since it now checks for the existance of the FS session safely.
*/
if ( switch_thread_rwlock_trywrlock_timeout(rsession->session_rwlock, 10) == SWITCH_STATUS_SUCCESS) {
switch_core_hash_delete(rsession->session_hash, switch_core_session_get_uuid(session));
switch_thread_rwlock_unlock(rsession->session_rwlock);
}
switch_mutex_lock(rsession->count_mutex);
rsession->active_sessions--;
switch_mutex_unlock(rsession->count_mutex);
#ifndef RTMP_DONT_HOLD #ifndef RTMP_DONT_HOLD
if (switch_channel_test_flag(channel, CF_HOLD)) { if (switch_channel_test_flag(channel, CF_HOLD)) {
switch_channel_mark_hold(channel, SWITCH_FALSE); switch_channel_mark_hold(channel, SWITCH_FALSE);
...@@ -841,6 +846,13 @@ switch_status_t rtmp_session_destroy(rtmp_session_t **rsession) ...@@ -841,6 +846,13 @@ switch_status_t rtmp_session_destroy(rtmp_session_t **rsession)
/* At this point we don't know if the session still exists, so request a fresh pointer to it from the core. */ /* At this point we don't know if the session still exists, so request a fresh pointer to it from the core. */
if ( (session = switch_core_session_locate((char *)key)) != NULL ) { if ( (session = switch_core_session_locate((char *)key)) != NULL ) {
switch_core_session_rwunlock(session); switch_core_session_rwunlock(session);
/*
* This is here so that if the FS session still exists and has the FS session write(or read) lock, then we won't destroy the rsession
* until the FS session is finished with it. But if the rsession is able to get the FS session
* write lock, before the FS session is hungup, then once the FS session does get the write lock
* the rsession pointer will be null, and the FS session will never try and touch the already destroyed rsession.
*/
switch_core_session_write_lock(session); switch_core_session_write_lock(session);
channel = switch_core_session_get_channel(session); channel = switch_core_session_get_channel(session);
tech_pvt = switch_core_session_get_private(session); tech_pvt = switch_core_session_get_private(session);
...@@ -853,11 +865,6 @@ switch_status_t rtmp_session_destroy(rtmp_session_t **rsession) ...@@ -853,11 +865,6 @@ switch_status_t rtmp_session_destroy(rtmp_session_t **rsession)
} }
switch_thread_rwlock_unlock((*rsession)->session_rwlock); switch_thread_rwlock_unlock((*rsession)->session_rwlock);
/* while ((*rsession)->active_sessions > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Still have %d sessions, waiting\n", (*rsession)->active_sessions);
switch_yield(500000);
}*/
switch_mutex_lock((*rsession)->profile->mutex); switch_mutex_lock((*rsession)->profile->mutex);
if ( (*rsession)->profile->calls < 1 ) { if ( (*rsession)->profile->calls < 1 ) {
(*rsession)->profile->calls = 0; (*rsession)->profile->calls = 0;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论