From: Sangchul Lee Date: Thu, 10 Aug 2017 10:57:53 +0000 (+0900) Subject: Add a mutex lock for focus callback X-Git-Tag: submit/tizen/20170828.011335~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3ccbc1cd880d92bf91b4917132a25efc2a4d09d1;p=platform%2Fcore%2Fapi%2Fsound-manager.git Add a mutex lock for focus callback [Version] 0.4.19 [Issue Type] Enhancement Change-Id: Iad902c6c3d44ac336ac37e4813d1124ac1a2b9d4 Signed-off-by: Sangchul Lee --- diff --git a/include/sound_manager_private.h b/include/sound_manager_private.h index eb93cf2..399bfd2 100644 --- a/include/sound_manager_private.h +++ b/include/sound_manager_private.h @@ -72,15 +72,44 @@ _CHECK_CONDITION(arg != NULL, MM_ERROR_INVALID_ARGUMENT, "MM_ERROR_INVALID_ARGUM #define SM_STATE_CHECK_FOR_PRIV(handle, expected_state) \ _CHECK_CONDITION(handle->state == expected_state, MM_ERROR_SOUND_INVALID_STATE, "MM_ERROR_SOUND_INVALID_STATE") +#define SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(x_mutex, x_mutex_to_unlock, x_return) \ +switch (pthread_mutex_lock(x_mutex)) { \ +case EINVAL: \ + LOGW("try mutex init.."); \ + if (pthread_mutex_init(x_mutex, NULL)) { \ + if (pthread_mutex_unlock(x_mutex_to_unlock)) \ + LOGE("mutex unlock failed"); \ + return x_return; \ + } else { \ + if (pthread_mutex_lock(x_mutex)) { \ + LOGE("mutex lock failed"); \ + if (pthread_mutex_unlock(x_mutex_to_unlock)) \ + LOGE("mutex unlock failed"); \ + return x_return; \ + } \ + break; \ + } \ + if (pthread_mutex_unlock(x_mutex_to_unlock)) \ + LOGE("mutex unlock failed"); \ + return x_return; \ +case 0: \ + break; \ +default: \ + LOGE("mutex lock failed"); \ + if (pthread_mutex_unlock(x_mutex_to_unlock)) \ + LOGE("mutex unlock failed"); \ + return x_return; \ +} + #define SM_ENTER_CRITICAL_SECTION_WITH_RETURN(x_mutex, x_return) \ switch (pthread_mutex_lock(x_mutex)) { \ case EINVAL: \ - LOGW("try mutex init..\n"); \ + LOGW("try mutex init.."); \ if (pthread_mutex_init(x_mutex, NULL)) { \ return x_return; \ } else { \ if (pthread_mutex_lock(x_mutex)) { \ - LOGE("mutex lock failed\n"); \ + LOGE("mutex lock failed"); \ return x_return; \ } \ break; \ @@ -89,13 +118,34 @@ case EINVAL: \ case 0: \ break; \ default: \ - LOGE("mutex lock failed\n"); \ + LOGE("mutex lock failed"); \ return x_return; \ } +#define SM_ENTER_CRITICAL_SECTION(x_mutex) \ +switch (pthread_mutex_lock(x_mutex)) { \ +case EINVAL: \ + LOGW("try mutex init.."); \ + if (pthread_mutex_init(x_mutex, NULL)) { \ + return; \ + } else { \ + if (pthread_mutex_lock(x_mutex)) { \ + LOGE("mutex lock failed"); \ + return; \ + } \ + break; \ + } \ + return; \ +case 0: \ + break; \ +default: \ + LOGE("mutex lock failed"); \ + return; \ +} + #define SM_LEAVE_CRITICAL_SECTION(x_mutex) \ if (pthread_mutex_unlock(x_mutex)) { \ - LOGE("mutex unlock failed\n"); \ + LOGE("mutex unlock failed"); \ } #define SM_REF_FOR_STREAM_INFO(x_count, x_return) \ @@ -178,6 +228,7 @@ typedef struct _sound_stream_info_s { void *user_data; manual_route_info_s manual_route_info; pthread_mutex_t focus_state_mutex; + pthread_mutex_t focus_cb_mutex; } sound_stream_info_s; typedef enum { diff --git a/packaging/capi-media-sound-manager.spec b/packaging/capi-media-sound-manager.spec index db498c6..6c00328 100644 --- a/packaging/capi-media-sound-manager.spec +++ b/packaging/capi-media-sound-manager.spec @@ -1,6 +1,6 @@ Name: capi-media-sound-manager Summary: Sound Manager library -Version: 0.4.18 +Version: 0.4.19 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/sound_manager.c b/src/sound_manager.c index b4c9d64..83e16d6 100644 --- a/src/sound_manager.c +++ b/src/sound_manager.c @@ -406,7 +406,12 @@ int sound_manager_acquire_focus(sound_stream_info_h stream_info, sound_stream_fo return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); } - SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL); + if (!is_focus_cb_thread) { + SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL); + SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL); + } else { + SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL); + } if (stream_h->acquired_focus & focus_mask) { LOGE("invalid state: focus_mask[0x%x], acquired_focus[0x%x]", focus_mask, stream_h->acquired_focus); @@ -432,6 +437,8 @@ int sound_manager_acquire_focus(sound_stream_info_h stream_info, sound_stream_fo LEAVE: SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex); + if (!is_focus_cb_thread) + SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex); return _convert_sound_manager_error_code(__func__, ret); } @@ -449,7 +456,12 @@ int sound_manager_release_focus(sound_stream_info_h stream_info, sound_stream_fo if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread))) return _convert_sound_manager_error_code(__func__, ret); - SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL); + if (!is_focus_cb_thread) { + SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL); + SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL); + } else { + SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL); + } if (!(stream_h->acquired_focus & focus_mask)) { LOGE("invalid state: focus_mask[0x%x], acquired_focus[0x%x]", focus_mask, stream_h->acquired_focus); @@ -475,6 +487,8 @@ int sound_manager_release_focus(sound_stream_info_h stream_info, sound_stream_fo LEAVE: SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex); + if (!is_focus_cb_thread) + SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex); return _convert_sound_manager_error_code(__func__, ret); } @@ -503,7 +517,12 @@ int sound_manager_acquire_focus_all(sound_stream_info_h stream_info, int sound_b return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); } - SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL); + if (!is_focus_cb_thread) { + SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL); + SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL); + } else { + SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL); + } if (is_focus_cb_thread && (stream_h->prev_acquired_focus > stream_h->acquired_focus)) { LOGE("just lost focus in this callback, it is not allowed to acquire all again. acquired_focus[0x%x], prev[0x%x]", @@ -528,6 +547,8 @@ int sound_manager_acquire_focus_all(sound_stream_info_h stream_info, int sound_b LEAVE: SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex); + if (!is_focus_cb_thread) + SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex); return _convert_sound_manager_error_code(__func__, ret); } @@ -545,7 +566,12 @@ int sound_manager_release_focus_all(sound_stream_info_h stream_info, int sound_b if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread))) return _convert_sound_manager_error_code(__func__, ret); - SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL); + if (!is_focus_cb_thread) { + SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL); + SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL); + } else { + SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL); + } if (is_focus_cb_thread && (stream_h->prev_acquired_focus < stream_h->acquired_focus)) { LOGE("just acquired focus in this callback, it is not allowed to release all again. acquired_focus[0x%x], prev[0x%x]", @@ -569,6 +595,8 @@ int sound_manager_release_focus_all(sound_stream_info_h stream_info, int sound_b LEAVE: SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex); + if (!is_focus_cb_thread) + SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex); return _convert_sound_manager_error_code(__func__, ret); } diff --git a/src/sound_manager_private.c b/src/sound_manager_private.c index 207ce5e..9d48319 100644 --- a/src/sound_manager_private.c +++ b/src/sound_manager_private.c @@ -581,6 +581,8 @@ void _focus_state_change_callback(int index, mm_sound_focus_type_e focus_type, m goto LEAVE; } + SM_ENTER_CRITICAL_SECTION(&stream_info->focus_cb_mutex); + if (state == FOCUS_IS_RELEASED) stream_info->acquired_focus &= ~focus_type; else if (state == FOCUS_IS_ACQUIRED) @@ -602,6 +604,8 @@ void _focus_state_change_callback(int index, mm_sound_focus_type_e focus_type, m else if (state == FOCUS_IS_ACQUIRED) stream_info->prev_acquired_focus |= focus_type; + SM_LEAVE_CRITICAL_SECTION(&stream_info->focus_cb_mutex); + LEAVE: LOGI("<< leave");