Add defensive code for clearing locked mutex 97/313497/1 accepted/tizen/8.0/unified/20240701.172933
authorJeongmo Yang <jm80.yang@samsung.com>
Wed, 19 Jun 2024 05:02:00 +0000 (14:02 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Thu, 27 Jun 2024 00:51:32 +0000 (09:51 +0900)
- The mutex can be cleared although it's locked while calling client user callback.
- Add defensive code to avoid clearing locked mutex.

[Version] 0.4.120
[Issue Type] Improvement

Change-Id: Ib6abaeba5a05c5cdb7f5667c4719c6a2e89bdfe2
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
packaging/capi-media-camera.spec
src/camera.c

index 147ca363438f43fb6fd43176ec9b852ef908b300..59b59ee02bc3797af5be18f04666c4391a014240 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-camera
 Summary:    A Camera API
-Version:    0.4.119
+Version:    0.4.120
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index bd33b1ea339b5eb4ba9d8fe7affeeadc95ac9786..c4b42910a9188b043ca29a2a8731567a7a3ff44b 100644 (file)
@@ -1748,6 +1748,8 @@ static void __camera_client_user_callback(camera_cb_info_s *cb_info, char *recv_
        }
 
        g_mutex_unlock(&cb_info->user_cb_mutex[event]);
+
+       CAM_LOG_DEBUG("done - event[%d]", event);
 }
 
 static gboolean __camera_idle_event_callback(gpointer data)
@@ -2395,8 +2397,17 @@ static void __camera_mutex_cond_clear(camera_cb_info_s *cb_info)
        g_mutex_clear(&cb_info->mp_data_mutex);
        g_mutex_clear(&cb_info->bridge_lock);
 
-       for (i = 0 ; i < MUSE_CAMERA_EVENT_TYPE_NUM ; i++)
+       for (i = 0 ; i < MUSE_CAMERA_EVENT_TYPE_NUM ; i++) {
+               /* The mutex can be locked when the user callback is called in idle callback.
+                  This code will wait until it's unlocked and avoid crash by clearing locked mutex. */
+               if (!g_mutex_trylock(&cb_info->user_cb_mutex[i])) {
+                       CAM_LOG_WARNING("user_cb_mutex[%d] is locked somewhere", i);
+                       g_mutex_lock(&cb_info->user_cb_mutex[i]);
+               }
+
+               g_mutex_unlock(&cb_info->user_cb_mutex[i]);
                g_mutex_clear(&cb_info->user_cb_mutex[i]);
+       }
 
        for (i = 0 ; i < MUSE_CAMERA_API_MAX ; i++) {
                g_mutex_clear(&cb_info->api_mutex[i]);