From 86667d8d1a03a193018a4b8b12201b2613695435 Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Mon, 16 Oct 2017 16:29:07 +0900 Subject: [PATCH] Add mutex lock for event callback 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 --- include/recorder_private.h | 1 + packaging/capi-media-recorder.spec | 2 +- src/recorder.c | 142 +++++++++++++++++++++++++++++-------- 3 files changed, 114 insertions(+), 31 deletions(-) diff --git a/include/recorder_private.h b/include/recorder_private.h index 9955a9a..1e56eaf 100644 --- a/include/recorder_private.h +++ b/include/recorder_private.h @@ -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; diff --git a/packaging/capi-media-recorder.spec b/packaging/capi-media-recorder.spec index d9a48b2..88d7918 100644 --- a/packaging/capi-media-recorder.spec +++ b/packaging/capi-media-recorder.spec @@ -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 diff --git a/src/recorder.c b/src/recorder.c index 846cc9d..614ebcc 100644 --- a/src/recorder.c +++ b/src/recorder.c @@ -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); -- 2.7.4