Add defensive code for clearing locked mutex 33/313533/1
authorJeongmo Yang <jm80.yang@samsung.com>
Wed, 19 Jun 2024 05:02:00 +0000 (14:02 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Wed, 19 Jun 2024 06:26:44 +0000 (15:26 +0900)
- The mutex can be cleared although it's locked while calling client user callback.
- Add defensive code to avoid clearing locked mutex.

[Version] 1.0.2
[Issue Type] Improvement

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

index 29928a6600ee4ba28501573502d6a08d43026e8b..75d5fa3267216c86c276802266c1202f4647e9b0 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-camera
 Summary:    A Camera API
-Version:    1.0.1
+Version:    1.0.2
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 1f4fa411f6d060014f0e03d34dd7834cd1e42d02..24f0193a135600d32d7cb2f572a6f1eaae446446 100644 (file)
@@ -1713,6 +1713,8 @@ static void __camera_client_user_callback(camera_cb_info_s *cb_info, char *recv_
                CAM_LOG_WARNING("unhandled event %d", event);
                break;
        }
+
+       CAM_LOG_DEBUG("done - event[%d]", event);
 }
 
 static gboolean __camera_idle_event_callback(gpointer data)
@@ -2367,8 +2369,17 @@ static void __camera_mutex_cond_clear(camera_cb_info_s *cb_info)
        g_mutex_clear(&cb_info->mp_data_lock);
        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_lock[i])) {
+                       CAM_LOG_WARNING("user_cb_lock[%d] is locked somewhere", i);
+                       g_mutex_lock(&cb_info->user_cb_lock[i]);
+               }
+
+               g_mutex_unlock(&cb_info->user_cb_lock[i]);
                g_mutex_clear(&cb_info->user_cb_lock[i]);
+       }
 
        for (i = 0 ; i < MUSE_CAMERA_API_MAX ; i++) {
                g_mutex_clear(&cb_info->api_lock[i]);