Add mutex lock for event callback 01/155801/1 accepted/tizen/unified/20171017.204834 submit/tizen/20171017.063236
authorJeongmo Yang <jm80.yang@samsung.com>
Mon, 16 Oct 2017 07:29:07 +0000 (16:29 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Mon, 16 Oct 2017 07:29:07 +0000 (16:29 +0900)
In some case, event callback could be called after unsetting is done by timing.
So, this patch is added to prevent the case.

[Version] 0.3.6
[Profile] Common
[Issue Type] Bug fix
[Dependency module] N/A
[Test] [M(T) - Boot=(OK), sdb=(OK), Home=(OK), Touch=(OK), Version=tizen-4.0-unified_20171013.1]

Change-Id: I4af49048775cce65d6802291bcb4408d97a55d40
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
include/recorder_private.h
packaging/capi-media-recorder.spec
src/recorder.c

index 9955a9a..1e56eaf 100644 (file)
@@ -108,6 +108,7 @@ typedef struct _recorder_cb_info_s {
        /* user callback */
        gpointer user_cb[MUSE_RECORDER_EVENT_TYPE_NUM];
        gpointer user_data[MUSE_RECORDER_EVENT_TYPE_NUM];
+       GMutex user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_NUM];
 
        /* tbm */
        tbm_bufmgr bufmgr;
index d9a48b2..88d7918 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-recorder
 Summary:    A Recorder API
-Version:    0.3.5
+Version:    0.3.6
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 846cc9d..614ebcc 100644 (file)
@@ -170,9 +170,17 @@ static void _recorder_client_user_callback(recorder_cb_info_s *cb_info, char *re
 
        /*LOGD("get recorder msg %s, event %d", recv_msg, event);*/
 
+       g_mutex_lock(&cb_info->user_cb_mutex[event]);
+
        if (cb_info->user_cb[event] == NULL) {
-               LOGW("user callback for event %d is not set", event);
-               return;
+               if (event != MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM &&
+                       event != MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM) {
+                       g_mutex_unlock(&cb_info->user_cb_mutex[event]);
+                       LOGW("NULL callback for event %d, return here", event);
+                       return;
+               } else {
+                       LOGW("NULL callback for event %d, NOT return here", event);
+               }
        }
 
        switch (event) {
@@ -276,25 +284,23 @@ static void _recorder_client_user_callback(recorder_cb_info_s *cb_info, char *re
                                break;
                        }
 
-                       if (!_recorder_import_tbm_key(cb_info->bufmgr, tbm_key, &bo, &bo_handle)) {
-                               LOGE("tbm key %d import failed", tbm_key);
-                               break;
-                       }
+                       if (cb_info->user_cb[event]) {
+                               if (_recorder_import_tbm_key(cb_info->bufmgr, tbm_key, &bo, &bo_handle)) {
+                                       muse_recorder_msg_get(size, recv_msg);
+                                       muse_recorder_msg_get(format, recv_msg);
+                                       muse_recorder_msg_get(channel, recv_msg);
+                                       muse_recorder_msg_get(timestamp, recv_msg);
 
-                       muse_recorder_msg_get(size, recv_msg);
-                       muse_recorder_msg_get(format, recv_msg);
-                       muse_recorder_msg_get(channel, recv_msg);
-                       muse_recorder_msg_get(timestamp, recv_msg);
-
-                       ((recorder_audio_stream_cb)cb_info->user_cb[event])((void *)bo_handle.ptr,
-                               size,
-                               (audio_sample_type_e)format,
-                               channel,
-                               (unsigned int)timestamp,
-                               cb_info->user_data[event]);
+                                       ((recorder_audio_stream_cb)cb_info->user_cb[event])((void *)bo_handle.ptr,
+                                               size, (audio_sample_type_e)format, channel,
+                                               (unsigned int)timestamp, cb_info->user_data[event]);
 
-                       /* release imported bo */
-                       _recorder_release_imported_bo(&bo);
+                                       /* release imported bo */
+                                       _recorder_release_imported_bo(&bo);
+                               } else {
+                                       LOGE("tbm key %d import failed", tbm_key);
+                               }
+                       }
 
                        /* return buffer */
                        send_msg = muse_core_msg_new(MUSE_RECORDER_API_RETURN_BUFFER,
@@ -322,19 +328,20 @@ static void _recorder_client_user_callback(recorder_cb_info_s *cb_info, char *re
                                break;
                        }
 
-                       if (!_recorder_import_tbm_key(cb_info->bufmgr, tbm_key, &bo, &bo_handle)) {
-                               LOGE("tbm key %d import failed", tbm_key);
-                               break;
-                       }
+                       if (cb_info->user_cb[event]) {
+                               if (_recorder_import_tbm_key(cb_info->bufmgr, tbm_key, &bo, &bo_handle)) {
+                                       muse_recorder_msg_get(size, recv_msg);
+                                       muse_recorder_msg_get(offset, recv_msg);
 
-                       muse_recorder_msg_get(size, recv_msg);
-                       muse_recorder_msg_get(offset, recv_msg);
+                                       ((recorder_muxed_stream_cb)cb_info->user_cb[event])((void *)bo_handle.ptr,
+                                               size, (unsigned long long)offset, cb_info->user_data[event]);
 
-                       ((recorder_muxed_stream_cb)cb_info->user_cb[event])((void *)bo_handle.ptr,
-                               size, (unsigned long long)offset, cb_info->user_data[event]);
-
-                       /* release imported bo */
-                       _recorder_release_imported_bo(&bo);
+                                       /* release imported bo */
+                                       _recorder_release_imported_bo(&bo);
+                               } else {
+                                       LOGE("tbm key %d import failed", tbm_key);
+                               }
+                       }
 
                        /* return buffer */
                        send_msg = muse_core_msg_new(MUSE_RECORDER_API_RETURN_BUFFER,
@@ -426,6 +433,8 @@ static void _recorder_client_user_callback(recorder_cb_info_s *cb_info, char *re
                }
        }
 
+       g_mutex_unlock(&cb_info->user_cb_mutex[event]);
+
        return;
 }
 
@@ -1178,6 +1187,9 @@ static recorder_cb_info_s *_recorder_client_callback_new(gint sockfd)
        g_mutex_init(&cb_info->idle_event_mutex);
        g_cond_init(&cb_info->idle_event_cond);
 
+       for (i = 0 ; i < MUSE_RECORDER_EVENT_TYPE_NUM ; i++)
+               g_mutex_init(&cb_info->user_cb_mutex[i]);
+
        /* message handler thread */
        if (!__create_msg_handler_thread(&cb_info->msg_handler_info,
                _RECORDER_MESSAGE_HANDLER_TYPE_GENERAL, "recorder_msg_handler", cb_info)) {
@@ -1220,6 +1232,9 @@ ErrorExit:
                __destroy_msg_handler_thread(&cb_info->audio_stream_cb_info);
                __destroy_msg_handler_thread(&cb_info->muxed_stream_cb_info);
 
+               for (i = 0 ; i < MUSE_RECORDER_EVENT_TYPE_NUM ; i++)
+                       g_mutex_clear(&cb_info->user_cb_mutex[i]);
+
                g_mutex_clear(&cb_info->idle_event_mutex);
                g_cond_clear(&cb_info->idle_event_cond);
 
@@ -1402,6 +1417,9 @@ static void _recorder_client_callback_destroy(recorder_cb_info_s *cb_info)
        __destroy_msg_handler_thread(&cb_info->audio_stream_cb_info);
        __destroy_msg_handler_thread(&cb_info->muxed_stream_cb_info);
 
+       for (i = 0 ; i < MUSE_RECORDER_EVENT_TYPE_NUM ; i++)
+               g_mutex_clear(&cb_info->user_cb_mutex[i]);
+
        g_mutex_clear(&cb_info->idle_event_mutex);
        g_cond_clear(&cb_info->idle_event_cond);
 
@@ -2277,8 +2295,12 @@ int recorder_set_state_changed_cb(recorder_h recorder, recorder_state_changed_cb
        _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
 
        if (ret == RECORDER_ERROR_NONE) {
+               g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE]);
+
                pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE] = callback;
                pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE] = user_data;
+
+               g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE]);
        }
 
        LOGD("ret : 0x%x", ret);
@@ -2303,8 +2325,12 @@ int recorder_unset_state_changed_cb(recorder_h recorder)
        _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
 
        if (ret == RECORDER_ERROR_NONE) {
+               g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE]);
+
                pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE] = NULL;
                pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE] = NULL;
+
+               g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE]);
        }
 
        LOGD("ret : 0x%x", ret);
@@ -2329,8 +2355,12 @@ int recorder_set_interrupted_cb(recorder_h recorder, recorder_interrupted_cb cal
        _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
 
        if (ret == RECORDER_ERROR_NONE) {
+               g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED]);
+
                pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED] = callback;
                pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED] = user_data;
+
+               g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED]);
        }
 
        LOGD("ret : 0x%x", ret);
@@ -2355,8 +2385,12 @@ int recorder_unset_interrupted_cb(recorder_h recorder)
        _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
 
        if (ret == RECORDER_ERROR_NONE) {
+               g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED]);
+
                pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED] = NULL;
                pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED] = NULL;
+
+               g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED]);
        }
 
        LOGD("ret : 0x%x", ret);
@@ -2381,8 +2415,12 @@ int recorder_set_interrupt_started_cb(recorder_h recorder, recorder_interrupt_st
        _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
 
        if (ret == RECORDER_ERROR_NONE) {
+               g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED]);
+
                pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED] = callback;
                pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED] = user_data;
+
+               g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED]);
        }
 
        LOGD("ret : 0x%x", ret);
@@ -2407,8 +2445,12 @@ int recorder_unset_interrupt_started_cb(recorder_h recorder)
        _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
 
        if (ret == RECORDER_ERROR_NONE) {
+               g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED]);
+
                pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED] = NULL;
                pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED] = NULL;
+
+               g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED]);
        }
 
        LOGD("ret : 0x%x", ret);
@@ -2433,8 +2475,12 @@ int recorder_set_audio_stream_cb(recorder_h recorder, recorder_audio_stream_cb c
        _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
 
        if (ret == RECORDER_ERROR_NONE) {
+               g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM]);
+
                pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM] = callback;
                pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM] = user_data;
+
+               g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM]);
        }
 
        LOGD("ret : 0x%x", ret);
@@ -2459,8 +2505,12 @@ int recorder_unset_audio_stream_cb(recorder_h recorder)
        _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
 
        if (ret == RECORDER_ERROR_NONE) {
+               g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM]);
+
                pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM] = NULL;
                pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM] = NULL;
+
+               g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM]);
        }
 
        LOGD("ret : 0x%x", ret);
@@ -2485,8 +2535,12 @@ int recorder_set_muxed_stream_cb(recorder_h recorder, recorder_muxed_stream_cb c
        _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
 
        if (ret == RECORDER_ERROR_NONE) {
+               g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM]);
+
                pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM] = callback;
                pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM] = user_data;
+
+               g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM]);
        }
 
        LOGD("ret : 0x%x", ret);
@@ -2511,8 +2565,12 @@ int recorder_unset_muxed_stream_cb(recorder_h recorder)
        _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
 
        if (ret == RECORDER_ERROR_NONE) {
+               g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM]);
+
                pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM] = NULL;
                pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM] = NULL;
+
+               g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM]);
        }
 
        LOGD("ret : 0x%x", ret);
@@ -2537,8 +2595,12 @@ int recorder_set_error_cb(recorder_h recorder, recorder_error_cb callback, void
        _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
 
        if (ret == RECORDER_ERROR_NONE) {
+               g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_ERROR]);
+
                pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_ERROR] = callback;
                pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_ERROR] = user_data;
+
+               g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_ERROR]);
        }
 
        LOGD("ret : 0x%x", ret);
@@ -2563,8 +2625,12 @@ int recorder_unset_error_cb(recorder_h recorder)
        _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
 
        if (ret == RECORDER_ERROR_NONE) {
+               g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_ERROR]);
+
                pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_ERROR] = NULL;
                pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_ERROR] = NULL;
+
+               g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_ERROR]);
        }
 
        LOGD("ret : 0x%x", ret);
@@ -2589,8 +2655,12 @@ int recorder_set_recording_status_cb(recorder_h recorder, recorder_recording_sta
        _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
 
        if (ret == RECORDER_ERROR_NONE) {
+               g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS]);
+
                pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS] = callback;
                pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS] = user_data;
+
+               g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS]);
        }
 
        LOGD("ret : 0x%x", ret);
@@ -2615,8 +2685,12 @@ int recorder_unset_recording_status_cb(recorder_h recorder)
        _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
 
        if (ret == RECORDER_ERROR_NONE) {
+               g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS]);
+
                pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS] = NULL;
                pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS] = NULL;
+
+               g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS]);
        }
 
        LOGD("ret : 0x%x", ret);
@@ -2639,8 +2713,12 @@ int recorder_set_recording_limit_reached_cb(recorder_h recorder, recorder_record
        _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
 
        if (ret == RECORDER_ERROR_NONE) {
+               g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED]);
+
                pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED] = callback;
                pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED] = user_data;
+
+               g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED]);
        }
 
        LOGD("ret : 0x%x", ret);
@@ -2665,8 +2743,12 @@ int recorder_unset_recording_limit_reached_cb(recorder_h recorder)
        _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
 
        if (ret == RECORDER_ERROR_NONE) {
+               g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED]);
+
                pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED] = NULL;
                pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED] = NULL;
+
+               g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED]);
        }
 
        LOGD("ret : 0x%x", ret);