Add a mutex lock for focus callback 72/143572/4
authorSangchul Lee <sc11.lee@samsung.com>
Thu, 10 Aug 2017 10:57:53 +0000 (19:57 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Tue, 22 Aug 2017 05:20:48 +0000 (14:20 +0900)
[Version] 0.4.19
[Issue Type] Enhancement

Change-Id: Iad902c6c3d44ac336ac37e4813d1124ac1a2b9d4
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
include/sound_manager_private.h
packaging/capi-media-sound-manager.spec
src/sound_manager.c
src/sound_manager_private.c

index eb93cf2c9bb6fc8d2bd21199915b3c132a697459..399bfd2960f7028e02fae9494a8f8b21f6a2b95c 100644 (file)
@@ -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 {
index db498c63430de4f84b8be4ba346c65cd106afe0f..6c00328cbf305073ee18bf0679929bc366607917 100644 (file)
@@ -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
index b4c9d64ee9151129279cd66559c617487281c9f6..83e16d6e6828414e8a95a325c029c2135b7ea9b8 100644 (file)
@@ -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);
 }
index 207ce5e7da0080a64df872f5e77592fdb3ca550e..9d483197ebb9a8531c9add28f17483572a273ab1 100644 (file)
@@ -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");