]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
[Core] Fix possible race condition between locking a session and reading it's flags... 1727/head
authorAndrey Volk <andywolk@gmail.com>
Sat, 23 Jul 2022 19:07:40 +0000 (22:07 +0300)
committerAndrey Volk <andywolk@gmail.com>
Mon, 25 Jul 2022 22:49:31 +0000 (01:49 +0300)
src/switch_core_rwlock.c

index 61c9ca45b990e5b7a45dce2c9e8ab75522ae0633..69e188ed79e48b0205037affdd446aab00df2932 100644 (file)
@@ -85,9 +85,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_lock(switch_core_sessio
        switch_status_t status = SWITCH_STATUS_FALSE;
 
        if (session->rwlock) {
-               if (switch_test_flag(session, SSF_DESTROYED) || switch_channel_down_nosig(session->channel)) {
-                       status = SWITCH_STATUS_FALSE;
-                       if (switch_thread_rwlock_tryrdlock(session->rwlock) == SWITCH_STATUS_SUCCESS) {
+               if ((status = switch_thread_rwlock_tryrdlock(session->rwlock)) == SWITCH_STATUS_SUCCESS) {
+                       if (switch_test_flag(session, SSF_DESTROYED) || switch_channel_down_nosig(session->channel)) {
+                               status = SWITCH_STATUS_FALSE;
                                if (switch_channel_test_flag(session->channel, CF_THREAD_SLEEPING)) {
 #ifdef SWITCH_DEBUG_RWLOCKS
                                        switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(session), SWITCH_LOG_ERROR, "%s %s Ping thread\n",
@@ -95,18 +95,18 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_lock(switch_core_sessio
 #endif
                                        switch_core_session_wake_session_thread(session);
                                }
-                               switch_thread_rwlock_unlock(session->rwlock);
-                       }
+
 #ifdef SWITCH_DEBUG_RWLOCKS
-                       switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(session), SWITCH_LOG_ERROR, "%s %s Read lock FAIL\n",
-                                                         switch_core_session_get_uuid(session), switch_channel_get_name(session->channel));
+                               switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(session), SWITCH_LOG_ERROR, "%s %s Read lock FAIL\n",
+                                                                 switch_core_session_get_uuid(session), switch_channel_get_name(session->channel));
 #endif
-               } else {
-                       status = (switch_status_t) switch_thread_rwlock_tryrdlock(session->rwlock);
+                               switch_thread_rwlock_unlock(session->rwlock);
+                       } else {
 #ifdef SWITCH_DEBUG_RWLOCKS
-                       switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(session), SWITCH_LOG_ERROR, "%s %s Read lock ACQUIRED\n",
-                                                         switch_core_session_get_uuid(session), switch_channel_get_name(session->channel));
+                               switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(session), SWITCH_LOG_ERROR, "%s %s Read lock ACQUIRED\n",
+                                                                 switch_core_session_get_uuid(session), switch_channel_get_name(session->channel));
 #endif
+                       }
                }
        }
 
@@ -123,18 +123,20 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_lock_hangup(switch_core
        switch_status_t status = SWITCH_STATUS_FALSE;
 
        if (session->rwlock) {
-               if (switch_test_flag(session, SSF_DESTROYED) || switch_channel_get_state(session->channel) >= CS_DESTROY) {
-                       status = SWITCH_STATUS_FALSE;
+               if ((status = switch_thread_rwlock_tryrdlock(session->rwlock)) == SWITCH_STATUS_SUCCESS) {
+                       if (switch_test_flag(session, SSF_DESTROYED) || switch_channel_get_state(session->channel) >= CS_DESTROY) {
+                               status = SWITCH_STATUS_FALSE;
 #ifdef SWITCH_DEBUG_RWLOCKS
-                       switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(session), SWITCH_LOG_ERROR, "%s %s Read lock FAIL\n",
-                                                         switch_core_session_get_uuid(session), switch_channel_get_name(session->channel));
+                               switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(session), SWITCH_LOG_ERROR, "%s %s Read lock FAIL\n",
+                                                                 switch_core_session_get_uuid(session), switch_channel_get_name(session->channel));
 #endif
-               } else {
-                       status = (switch_status_t) switch_thread_rwlock_tryrdlock(session->rwlock);
+                               switch_thread_rwlock_unlock(session->rwlock);
+                       } else {
 #ifdef SWITCH_DEBUG_RWLOCKS
-                       switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(session), SWITCH_LOG_ERROR, "%s %s Read lock ACQUIRED\n",
-                                                         switch_core_session_get_uuid(session), switch_channel_get_name(session->channel));
+                               switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(session), SWITCH_LOG_ERROR, "%s %s Read lock ACQUIRED\n",
+                                                                 switch_core_session_get_uuid(session), switch_channel_get_name(session->channel));
 #endif
+                       }
                }
        }