]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
[core] Improve session recording thread performance.
authorAndrey Volk <andywolk@gmail.com>
Fri, 22 Oct 2021 17:37:42 +0000 (20:37 +0300)
committerAndrey Volk <andywolk@gmail.com>
Sat, 23 Oct 2021 18:59:53 +0000 (21:59 +0300)
src/switch_ivr_async.c

index a08223393c7160e12cd70f7e6fc7389a4d42a439..357ea3f07a4af809c4e8bd253a05185aaef6ed7b 100644 (file)
@@ -1157,6 +1157,8 @@ struct record_helper {
        const char *completion_cause;
        int start_event_sent;
        switch_event_t *variables;
+       switch_mutex_t *cond_mutex;
+       switch_thread_cond_t *cond;
 };
 
 static switch_status_t record_helper_destroy(struct record_helper **rh, switch_core_session_t *session);
@@ -1261,17 +1263,21 @@ static void *SWITCH_THREAD_FUNC recording_thread(switch_thread_t *thread, void *
        }
 
        rh = switch_core_media_bug_get_user_data(bug);
-       switch_buffer_create_dynamic(&rh->thread_buffer, 1024 * 512, 1024 * 64, 0);
+       switch_buffer_create_dynamic(&rh->thread_buffer, SWITCH_RECOMMENDED_BUFFER_SIZE, SWITCH_RECOMMENDED_BUFFER_SIZE, 0);
        rh->thread_ready = 1;
 
        channels = switch_core_media_bug_test_flag(bug, SMBF_STEREO) ? 2 : rh->read_impl.number_of_channels;
        data = switch_core_alloc(rh->helper_pool, SWITCH_RECOMMENDED_BUFFER_SIZE);
 
+       switch_mutex_lock(rh->cond_mutex);
+
        while(switch_test_flag(rh->fh, SWITCH_FILE_OPEN)) {
                if (rh->thread_needs_transfer) {
                        assert(session != rh->recording_session);
 
                        if (switch_core_session_read_lock(rh->recording_session) != SWITCH_STATUS_SUCCESS) {
+                               /* Wait until recording is reverted to the original session */
+                               switch_thread_cond_wait(rh->cond, rh->cond_mutex);
                                continue;
                        }
 
@@ -1298,15 +1304,19 @@ static void *SWITCH_THREAD_FUNC recording_thread(switch_thread_t *thread, void *
                switch_mutex_lock(rh->buffer_mutex);
                inuse = switch_buffer_inuse(rh->thread_buffer);
 
-               if (rh->thread_ready && switch_channel_up_nosig(channel) && inuse < bsize) {
-                       switch_mutex_unlock(rh->buffer_mutex);
-                       switch_yield(20000);
-                       continue;
-               } else if ((!rh->thread_ready || switch_channel_down_nosig(channel)) && !inuse) {
+               if ((!rh->thread_ready || switch_channel_down_nosig(channel)) && !inuse) {
                        switch_mutex_unlock(rh->buffer_mutex);
                        break;
                }
 
+               if (!inuse) {
+                       switch_mutex_unlock(rh->buffer_mutex);
+                       if (rh->thread_ready) {
+                               switch_thread_cond_wait(rh->cond, rh->cond_mutex);
+                       }
+                       continue;
+               }
+
                samples = switch_buffer_read(rh->thread_buffer, data, bsize) / 2 / channels;
                switch_mutex_unlock(rh->buffer_mutex);
 
@@ -1321,6 +1331,8 @@ static void *SWITCH_THREAD_FUNC recording_thread(switch_thread_t *thread, void *
                }
        }
 
+       switch_mutex_unlock(rh->cond_mutex);
+
        switch_core_session_rwunlock(session);
 
        return NULL;
@@ -1362,6 +1374,10 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s
                                        rh->bug = bug;
                                        rh->thread_needs_transfer = 1;
 
+                                       switch_mutex_lock(rh->cond_mutex);
+                                       switch_thread_cond_signal(rh->cond);
+                                       switch_mutex_unlock(rh->cond_mutex);
+
                                        while (--sanity > 0 && rh->thread_needs_transfer) {
                                                switch_yield(10000);
                                        }
@@ -1399,8 +1415,11 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s
                                int sanity = 200;
 
                                switch_mutex_init(&rh->buffer_mutex, SWITCH_MUTEX_NESTED, rh->helper_pool);
+                               switch_mutex_init(&rh->cond_mutex, SWITCH_MUTEX_NESTED, rh->helper_pool);
+                               switch_thread_cond_create(&rh->cond, rh->helper_pool);
                                switch_threadattr_create(&thd_attr, rh->helper_pool);
                                switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
+                               switch_threadattr_priority_set(thd_attr, SWITCH_PRI_LOW);
                                switch_thread_create(&rh->thread, thd_attr, recording_thread, bug, rh->helper_pool);
 
                                while(--sanity > 0 && !rh->thread_ready) {
@@ -1535,6 +1554,11 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s
                                        switch_status_t st;
 
                                        rh->thread_ready = 0;
+
+                                       switch_mutex_lock(rh->cond_mutex);
+                                       switch_thread_cond_signal(rh->cond);
+                                       switch_mutex_unlock(rh->cond_mutex);
+
                                        switch_thread_join(&st, rh->thread);
                                }
 
@@ -1542,7 +1566,6 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s
                                        switch_buffer_destroy(&rh->thread_buffer);
                                }
 
-
                                frame.data = data;
                                frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
 
@@ -1663,6 +1686,10 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s
                                                switch_mutex_lock(rh->buffer_mutex);
                                                switch_buffer_write(rh->thread_buffer, mask ? null_data : data, frame.datalen);
                                                switch_mutex_unlock(rh->buffer_mutex);
+                                               if (switch_mutex_trylock(rh->cond_mutex) == SWITCH_STATUS_SUCCESS) {
+                                                       switch_thread_cond_signal(rh->cond);
+                                                       switch_mutex_unlock(rh->cond_mutex);
+                                               }
                                        } else if (switch_core_file_write(rh->fh, mask ? null_data : data, &len) != SWITCH_STATUS_SUCCESS) {
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error writing %s\n", rh->file);
                                                /* File write failed */