Skip locking focus_state mutex if sound_manager_get_focus_state() is called in focus... 30/266030/1 accepted/tizen/unified/20211109.042859 submit/tizen/20211108.065142 submit/tizen/20211108.233216
authorSangchul Lee <sc11.lee@samsung.com>
Thu, 4 Nov 2021 06:50:55 +0000 (15:50 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 4 Nov 2021 06:51:42 +0000 (15:51 +0900)
During destroying handle, it is possible that the focus state callback is
called simultaneously. The destroy function already lock the mutex also,
deadlock can occur if user calls the sound_manager_get_focus_state() function
inside of the focus state callback context. It is now fixed with this patch.

[Version] 0.6.39
[Issue Type] Improvement

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

index 41b2638..f180f19 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-sound-manager
 Summary:    Sound Manager library
-Version:    0.6.38
+Version:    0.6.39
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 6f7ab9b..e64e94b 100644 (file)
@@ -605,13 +605,19 @@ LEAVE:
 int sound_manager_get_focus_state(sound_stream_info_h stream_info, sound_stream_focus_state_e *state_for_playback, sound_stream_focus_state_e *state_for_recording)
 {
        sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
+       bool is_focus_cb_thread = false;
+       int mm_ret = MM_ERROR_NONE;
 
        SM_ARG_CHECK(stream_h);
        SM_ARG_CHECK(state_for_playback || state_for_recording);
 
        LOGI("stream_info[%p, type:%s, focus_id:%d]", stream_info, stream_h->stream_type, stream_h->focus_id);
 
-       SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, SOUND_MANAGER_ERROR_INTERNAL);
+       if ((mm_ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)) != MM_ERROR_NONE)
+               return _convert_sound_manager_error_code(__func__, mm_ret);
+
+       if (!is_focus_cb_thread)
+               SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, SOUND_MANAGER_ERROR_INTERNAL);
 
        if (state_for_playback)
                *state_for_playback = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_PLAYBACK) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
@@ -620,7 +626,8 @@ int sound_manager_get_focus_state(sound_stream_info_h stream_info, sound_stream_
 
        LOGI("acquired_focus(0x%x)", stream_h->acquired_focus);
 
-       SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
+       if (!is_focus_cb_thread)
+               SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
 
        return SOUND_MANAGER_ERROR_NONE;
 }