Update idle event handling to fix crash in idle event callback 91/191891/2
authorJeongmo Yang <jm80.yang@samsung.com>
Thu, 25 Oct 2018 01:52:34 +0000 (10:52 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Thu, 25 Oct 2018 04:51:12 +0000 (13:51 +0900)
- The idle event could be called after handle is destroyed.
- ASan issue : TDAF-748

[Version] 0.4.16
[Profile] Common
[Issue Type] Bug fix
[Dependency module] N/A

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

index fc8c578..4f24b7c 100644 (file)
@@ -132,8 +132,6 @@ typedef struct _camera_cb_info_s {
 
        /* idle event */
        GList *idle_event_list;
-       GCond idle_event_cond;
-       GMutex idle_event_mutex;
 
        /* user callback */
        gpointer user_cb[MUSE_CAMERA_EVENT_TYPE_NUM];
@@ -175,7 +173,6 @@ typedef struct _camera_idle_event_s {
        camera_cb_info_s *cb_info;
        gchar recv_msg[MUSE_CAMERA_MSG_MAX_LENGTH + 1];
        muse_camera_event_e event;
-       GMutex event_mutex;
 } camera_idle_event_s;
 
 typedef struct _camera_cli_s {
index f0fae57..58c995e 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-camera
 Summary:    A Camera API
-Version:    0.4.15
+Version:    0.4.16
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 28b1399..8c1447b 100644 (file)
@@ -41,6 +41,7 @@ static GList *g_cam_dev_state_changed_cb_list;
 static int g_cam_dev_state_changed_cb_id;
 static GDBusConnection *g_cam_dev_state_changed_cb_conn;
 static guint g_cam_dev_state_changed_cb_subscribe_id;
+static GMutex g_cam_idle_event_lock;
 
 static void _camera_msg_send(int api, camera_cb_info_s *cb_info,
        int *ret, int timeout);
@@ -1449,7 +1450,7 @@ static void _camera_client_user_callback(camera_cb_info_s *cb_info, char *recv_m
        return;
 }
 
-static bool _camera_idle_event_callback(void *data)
+static gboolean _camera_idle_event_callback(gpointer data)
 {
        camera_cb_info_s *cb_info = NULL;
        camera_idle_event_s *cam_idle_event = (camera_idle_event_s *)data;
@@ -1460,34 +1461,26 @@ static bool _camera_idle_event_callback(void *data)
        }
 
        /* lock event */
-       g_mutex_lock(&cam_idle_event->event_mutex);
+       g_mutex_lock(&g_cam_idle_event_lock);
 
        cb_info = cam_idle_event->cb_info;
        if (cb_info == NULL) {
                LOGW("camera cb_info is NULL. event %p %d", cam_idle_event, cam_idle_event->event);
+               g_mutex_unlock(&g_cam_idle_event_lock);
                goto IDLE_EVENT_CALLBACK_DONE;
        }
 
        /* remove event from list */
-       g_mutex_lock(&cb_info->idle_event_mutex);
-
        if (cb_info->idle_event_list)
                cb_info->idle_event_list = g_list_remove(cb_info->idle_event_list, (gpointer)cam_idle_event);
 
-       /*LOGD("remove camera idle event %p, %p", cam_idle_event, cb_info->idle_event_list);*/
-       g_mutex_unlock(&cb_info->idle_event_mutex);
+       g_mutex_unlock(&g_cam_idle_event_lock);
 
        /* user callback */
        _camera_client_user_callback(cb_info, cam_idle_event->recv_msg, cam_idle_event->event);
 
-       /* send signal for waiting thread */
-       g_cond_signal(&cb_info->idle_event_cond);
-
 IDLE_EVENT_CALLBACK_DONE:
-       /* unlock and release event */
-       g_mutex_unlock(&cam_idle_event->event_mutex);
-       g_mutex_clear(&cam_idle_event->event_mutex);
-
+       /* release event */
        g_free(cam_idle_event);
        cam_idle_event = NULL;
 
@@ -1574,14 +1567,14 @@ static void *_camera_msg_handler_func(gpointer data)
 
                                cam_idle_event->event = cam_msg->event;
                                cam_idle_event->cb_info = cb_info;
-                               g_mutex_init(&cam_idle_event->event_mutex);
+
                                strncpy(cam_idle_event->recv_msg, cam_msg->recv_msg, sizeof(cam_idle_event->recv_msg) - 1);
 
                                /*LOGD("t:%d add camera event[%d, %p] to IDLE", type, cam_msg->event, cam_idle_event);*/
 
-                               g_mutex_lock(&cb_info->idle_event_mutex);
+                               g_mutex_lock(&g_cam_idle_event_lock);
                                cb_info->idle_event_list = g_list_append(cb_info->idle_event_list, (gpointer)cam_idle_event);
-                               g_mutex_unlock(&cb_info->idle_event_mutex);
+                               g_mutex_unlock(&g_cam_idle_event_lock);
 
                                g_idle_add_full(G_PRIORITY_DEFAULT,
                                        (GSourceFunc)_camera_idle_event_callback,
@@ -1626,18 +1619,17 @@ static void _camera_deactivate_idle_event_all(camera_cb_info_s *cb_info)
 {
        camera_idle_event_s *cam_idle_event = NULL;
        GList *list = NULL;
-       gint64 end_time = 0;
 
        if (cb_info == NULL) {
                LOGE("cb_info is NULL");
                return;
        }
 
-       g_mutex_lock(&cb_info->idle_event_mutex);
+       g_mutex_lock(&g_cam_idle_event_lock);
 
        if (cb_info->idle_event_list == NULL) {
                LOGD("No remained idle event");
-               g_mutex_unlock(&cb_info->idle_event_mutex);
+               g_mutex_unlock(&g_cam_idle_event_lock);
                return;
        }
 
@@ -1657,42 +1649,24 @@ static void _camera_deactivate_idle_event_all(camera_cb_info_s *cb_info)
 
                        cb_info->idle_event_list = g_list_remove(cb_info->idle_event_list, (gpointer)cam_idle_event);
 
-                       g_mutex_clear(&cam_idle_event->event_mutex);
                        g_free(cam_idle_event);
                        cam_idle_event = NULL;
 
                        continue;
                }
 
-               LOGW("remove idle event %p failed", cam_idle_event);
-
-               if (!g_mutex_trylock(&cam_idle_event->event_mutex)) {
-                       LOGW("lock failed, %p event is calling now", cam_idle_event);
-
-                       end_time = g_get_monotonic_time() + G_TIME_SPAN_MILLISECOND * 100;
-
-                       if (g_cond_wait_until(&cb_info->idle_event_cond, &cb_info->idle_event_mutex, end_time))
-                               LOGW("signal received");
-                       else
-                               LOGW("timeout");
-
-                       continue;
-               }
-
                LOGW("set NULL cb_info for event %p %d, it will be freed on idle callback",
                        cam_idle_event, cam_idle_event->event);
 
                cam_idle_event->cb_info = NULL;
 
                cb_info->idle_event_list = g_list_remove(cb_info->idle_event_list, (gpointer)cam_idle_event);
-
-               g_mutex_unlock(&cam_idle_event->event_mutex);
        }
 
        g_list_free(cb_info->idle_event_list);
        cb_info->idle_event_list = NULL;
 
-       g_mutex_unlock(&cb_info->idle_event_mutex);
+       g_mutex_unlock(&g_cam_idle_event_lock);
 
        return;
 }
@@ -2123,8 +2097,6 @@ static camera_cb_info_s *_camera_client_callback_new(gint sockfd)
        }
 
        g_mutex_init(&cb_info->fd_lock);
-       g_mutex_init(&cb_info->idle_event_mutex);
-       g_cond_init(&cb_info->idle_event_cond);
        g_mutex_init(&cb_info->mp_data_mutex);
 
        for (i = 0 ; i < MUSE_CAMERA_EVENT_TYPE_NUM ; i++)
@@ -2177,8 +2149,6 @@ ErrorExit:
                        g_mutex_clear(&cb_info->user_cb_mutex[i]);
 
                g_mutex_clear(&cb_info->fd_lock);
-               g_mutex_clear(&cb_info->idle_event_mutex);
-               g_cond_clear(&cb_info->idle_event_cond);
                g_mutex_clear(&cb_info->mp_data_mutex);
 
                for (i = 0 ; i < MUSE_CAMERA_API_MAX ; i++) {
@@ -2215,8 +2185,6 @@ static void _camera_client_callback_destroy(camera_cb_info_s *cb_info)
                g_mutex_clear(&cb_info->user_cb_mutex[i]);
 
        g_mutex_clear(&cb_info->fd_lock);
-       g_mutex_clear(&cb_info->idle_event_mutex);
-       g_cond_clear(&cb_info->idle_event_cond);
        g_mutex_clear(&cb_info->mp_data_mutex);
 
        for (i = 0 ; i < MUSE_CAMERA_API_MAX ; i++) {