Improve thread handling 46/280046/5
authorJeongmo Yang <jm80.yang@samsung.com>
Tue, 23 Aug 2022 01:20:28 +0000 (10:20 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Thu, 25 Aug 2022 03:03:09 +0000 (12:03 +0900)
[Version] 0.4.86
[Issue Type] Improvement

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

index b9258a1..505ec6a 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-camera
 Summary:    A Camera API
-Version:    0.4.85
+Version:    0.4.86
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index c17f9a1..2d9b6a7 100644 (file)
@@ -1670,6 +1670,7 @@ static gpointer __camera_msg_handler_func(gpointer data)
        camera_idle_event_s *cam_idle_event = NULL;
        camera_msg_handler_info_s *handler_info = (camera_msg_handler_info_s *)data;
        camera_cb_info_s *cb_info = NULL;
+       GThread *thread = NULL;
 
        if (!handler_info || !handler_info->cb_info) {
                CAM_LOG_ERROR("NULL handler %p", handler_info);
@@ -1678,8 +1679,9 @@ static gpointer __camera_msg_handler_func(gpointer data)
 
        cb_info = (camera_cb_info_s *)handler_info->cb_info;
        type = handler_info->type;
+       thread = handler_info->thread;
 
-       CAM_LOG_INFO("t:%d start[thread:%p]", type, handler_info->thread);
+       CAM_LOG_INFO("t:%d start[thread:%p]", type, thread);
 
        g_mutex_lock(&handler_info->mutex);
 
@@ -1791,7 +1793,7 @@ static gpointer __camera_msg_handler_func(gpointer data)
 
        g_mutex_unlock(&handler_info->mutex);
 
-       CAM_LOG_INFO("t:%d return[thread:%p]", type, handler_info->thread);
+       CAM_LOG_INFO("t:%d return[thread:%p]", type, thread);
 
        return NULL;
 }
@@ -2142,6 +2144,8 @@ static bool __create_msg_handler_thread(camera_msg_handler_info_s *handler_info,
                return false;
        }
 
+       g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&handler_info->mutex);
+
        if (handler_info->thread) {
                CAM_LOG_WARNING("t:%d thread[%p] is already created", type, handler_info->thread);
                return true;
@@ -2156,9 +2160,6 @@ static bool __create_msg_handler_thread(camera_msg_handler_info_s *handler_info,
                return false;
        }
 
-       g_mutex_init(&handler_info->mutex);
-       g_cond_init(&handler_info->cond);
-
        handler_info->cb_info = (void *)cb_info;
        g_atomic_int_set(&handler_info->running, 1);
 
@@ -2167,8 +2168,6 @@ static bool __create_msg_handler_thread(camera_msg_handler_info_s *handler_info,
        if (handler_info->thread == NULL) {
                CAM_LOG_ERROR("t:%d thread failed", type);
 
-               g_mutex_clear(&handler_info->mutex);
-               g_cond_clear(&handler_info->cond);
                g_queue_free(handler_info->queue);
                handler_info->queue = NULL;
 
@@ -2183,65 +2182,119 @@ static bool __create_msg_handler_thread(camera_msg_handler_info_s *handler_info,
 
 static void __destroy_msg_handler_thread(camera_msg_handler_info_s *handler_info)
 {
-       int type = 0;
+       GThread *thread = NULL;
 
        if (!handler_info) {
                CAM_LOG_ERROR("NULL handler");
                return;
        }
 
+       g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&handler_info->mutex);
+
        if (!handler_info->thread) {
-               CAM_LOG_WARNING("thread is not created");
+               CAM_LOG_WARNING("thread[t:%d] is not created", handler_info->type);
                return;
        }
 
-       type = handler_info->type;
+       thread = handler_info->thread;
+       handler_info->thread = NULL;
 
-       CAM_LOG_INFO("t:%d thread[%p]", type, handler_info->thread);
+       CAM_LOG_INFO("t:%d thread[%p]", handler_info->type, thread);
 
-       g_mutex_lock(&handler_info->mutex);
        g_atomic_int_set(&handler_info->running, 0);
        g_cond_signal(&handler_info->cond);
-       g_mutex_unlock(&handler_info->mutex);
 
-       g_thread_join(handler_info->thread);
-       handler_info->thread = NULL;
+       g_clear_pointer(&locker, g_mutex_locker_free);
+
+       g_thread_join(thread);
 
-       g_mutex_clear(&handler_info->mutex);
-       g_cond_clear(&handler_info->cond);
        g_queue_free(handler_info->queue);
        handler_info->queue = NULL;
 
-       CAM_LOG_INFO("t:%d done", type);
+       CAM_LOG_INFO("t:%d done", handler_info->type);
 }
 
 
-static camera_cb_info_s *__camera_client_callback_new(gint sockfd)
+static void __camera_mutex_cond_init(camera_cb_info_s *cb_info)
 {
-       camera_cb_info_s *cb_info = NULL;
-       gint i = 0;
-
-       g_return_val_if_fail(sockfd > 0, NULL);
+       int i = 0;
 
-       cb_info = g_new0(camera_cb_info_s, 1);
-       if (cb_info == NULL) {
-               CAM_LOG_ERROR("cb_info failed");
-               goto ErrorExit;
+       if (!cb_info) {
+               CAM_LOG_ERROR("NULL cb_info");
+               return;
        }
 
-       cb_info->api_waiting[MUSE_CAMERA_API_CREATE] = 1;
-
        for (i = 0 ; i < MUSE_CAMERA_API_MAX ; i++) {
                g_mutex_init(&cb_info->api_mutex[i]);
                g_cond_init(&cb_info->api_cond[i]);
        }
 
+       for (i = 0 ; i < MUSE_CAMERA_EVENT_TYPE_NUM ; i++)
+               g_mutex_init(&cb_info->user_cb_mutex[i]);
+
        g_mutex_init(&cb_info->fd_lock);
        g_mutex_init(&cb_info->mp_data_mutex);
        g_mutex_init(&cb_info->bridge_lock);
 
+       g_mutex_init(&cb_info->msg_handler_info.mutex);
+       g_mutex_init(&cb_info->preview_cb_info.mutex);
+       g_mutex_init(&cb_info->capture_cb_info.mutex);
+       g_cond_init(&cb_info->msg_handler_info.cond);
+       g_cond_init(&cb_info->preview_cb_info.cond);
+       g_cond_init(&cb_info->capture_cb_info.cond);
+
+       CAM_LOG_INFO("done");
+}
+
+
+static void __camera_mutex_cond_clear(camera_cb_info_s *cb_info)
+{
+       int i = 0;
+
+       if (!cb_info) {
+               CAM_LOG_ERROR("NULL cb_info");
+               return;
+       }
+
+       g_mutex_clear(&cb_info->msg_handler_info.mutex);
+       g_mutex_clear(&cb_info->preview_cb_info.mutex);
+       g_mutex_clear(&cb_info->capture_cb_info.mutex);
+       g_cond_clear(&cb_info->msg_handler_info.cond);
+       g_cond_clear(&cb_info->preview_cb_info.cond);
+       g_cond_clear(&cb_info->capture_cb_info.cond);
+
+       g_mutex_clear(&cb_info->fd_lock);
+       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++)
-               g_mutex_init(&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]);
+               g_cond_clear(&cb_info->api_cond[i]);
+       }
+
+       CAM_LOG_INFO("done");
+}
+
+
+static camera_cb_info_s *__camera_client_callback_new(gint sockfd)
+{
+       camera_cb_info_s *cb_info = NULL;
+       gint i = 0;
+
+       g_return_val_if_fail(sockfd > 0, NULL);
+
+       cb_info = g_new0(camera_cb_info_s, 1);
+       if (!cb_info) {
+               CAM_LOG_ERROR("cb_info failed");
+               goto ErrorExit;
+       }
+
+       cb_info->api_waiting[MUSE_CAMERA_API_CREATE] = 1;
+
+       __camera_mutex_cond_init(cb_info);
 
        /* message handler thread */
        if (!__create_msg_handler_thread(&cb_info->msg_handler_info,
@@ -2281,17 +2334,7 @@ ErrorExit:
                __destroy_msg_handler_thread(&cb_info->msg_handler_info);
                __destroy_msg_handler_thread(&cb_info->capture_cb_info);
 
-               for (i = 0 ; i < MUSE_CAMERA_EVENT_TYPE_NUM ; i++)
-                       g_mutex_clear(&cb_info->user_cb_mutex[i]);
-
-               g_mutex_clear(&cb_info->fd_lock);
-               g_mutex_clear(&cb_info->mp_data_mutex);
-               g_mutex_clear(&cb_info->bridge_lock);
-
-               for (i = 0 ; i < MUSE_CAMERA_API_MAX ; i++) {
-                       g_mutex_clear(&cb_info->api_mutex[i]);
-                       g_cond_clear(&cb_info->api_cond[i]);
-               }
+               __camera_mutex_cond_clear(cb_info);
 
                g_free(cb_info);
                cb_info = NULL;
@@ -2301,11 +2344,13 @@ ErrorExit:
 //LCOV_EXCL_STOP
 }
 
+
 static void __camera_client_callback_destroy(camera_cb_info_s *cb_info)
 {
-       int i = 0;
-
-       g_return_if_fail(cb_info != NULL);
+       if (!cb_info) {
+               CAM_LOG_ERROR("NULL cb_info");
+               return;
+       }
 
        CAM_LOG_INFO("msg_recv thread[%p] destroy", cb_info->msg_recv_thread);
 
@@ -2315,22 +2360,11 @@ static void __camera_client_callback_destroy(camera_cb_info_s *cb_info)
        CAM_LOG_INFO("msg_recv thread removed");
 
        /* destroy msg handler threads */
-       if (cb_info->preview_cb_info.thread)
-               __destroy_msg_handler_thread(&cb_info->preview_cb_info);
+       __destroy_msg_handler_thread(&cb_info->preview_cb_info);
        __destroy_msg_handler_thread(&cb_info->msg_handler_info);
        __destroy_msg_handler_thread(&cb_info->capture_cb_info);
 
-       for (i = 0 ; i < MUSE_CAMERA_EVENT_TYPE_NUM ; i++)
-               g_mutex_clear(&cb_info->user_cb_mutex[i]);
-
-       g_mutex_clear(&cb_info->fd_lock);
-       g_mutex_clear(&cb_info->mp_data_mutex);
-       g_mutex_clear(&cb_info->bridge_lock);
-
-       for (i = 0 ; i < MUSE_CAMERA_API_MAX ; i++) {
-               g_mutex_clear(&cb_info->api_mutex[i]);
-               g_cond_clear(&cb_info->api_cond[i]);
-       }
+       __camera_mutex_cond_clear(cb_info);
 
        if (CAMERA_IS_FD_VALID(cb_info->fd)) {
                muse_client_close(cb_info->fd);