summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeongmo Yang <jm80.yang@samsung.com>2018-10-25 10:52:34 +0900
committerJeongmo Yang <jm80.yang@samsung.com>2018-10-25 13:49:40 +0900
commit64c5a0dbf468c0fdf76710c3bce1f0fb14bb3601 (patch)
tree4107b44758f940fd4e120674eae8eff6ebaba5c4
parentf9c2ba607eb3b701265f2da198d781d27e1df168 (diff)
downloadcamera-64c5a0dbf468c0fdf76710c3bce1f0fb14bb3601.tar.gz
camera-64c5a0dbf468c0fdf76710c3bce1f0fb14bb3601.tar.bz2
camera-64c5a0dbf468c0fdf76710c3bce1f0fb14bb3601.zip
Update idle event handling to fix crash in idle event callback
- The idle event could be called after handle is destroyed. - ASan issue : TDAF-748 [Version] 0.3.12 [Profile] Common [Issue Type] Bug fix [Dependency module] N/A Change-Id: I70466177edc1451669ef664f880fbb3f9f786f02 Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
-rw-r--r--include/camera_private.h3
-rw-r--r--packaging/capi-media-camera.spec2
-rw-r--r--src/camera.c56
3 files changed, 13 insertions, 48 deletions
diff --git a/include/camera_private.h b/include/camera_private.h
index 582d3d3..03aef07 100644
--- a/include/camera_private.h
+++ b/include/camera_private.h
@@ -131,8 +131,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_wl_info_s {
diff --git a/packaging/capi-media-camera.spec b/packaging/capi-media-camera.spec
index b7fa839..8980018 100644
--- a/packaging/capi-media-camera.spec
+++ b/packaging/capi-media-camera.spec
@@ -1,6 +1,6 @@
Name: capi-media-camera
Summary: A Camera API
-Version: 0.3.11
+Version: 0.3.12
Release: 0
Group: Multimedia/API
License: Apache-2.0
diff --git a/src/camera.c b/src/camera.c
index 69088f2..ef99d90 100644
--- a/src/camera.c
+++ b/src/camera.c
@@ -49,6 +49,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 __global(void *data, struct wl_registry *registry,
@@ -1589,7 +1590,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;
@@ -1600,34 +1601,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;
@@ -1714,14 +1707,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,
@@ -1766,18 +1759,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;
}
@@ -1797,42 +1789,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;
}
@@ -2258,8 +2232,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);
g_mutex_init(&cb_info->preview_cb_mutex);
#ifdef TIZEN_FEATURE_EVAS_RENDERER
@@ -2313,8 +2285,6 @@ ErrorExit:
__destroy_msg_handler_thread(&cb_info->capture_cb_info);
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);
g_mutex_clear(&cb_info->preview_cb_mutex);
#ifdef TIZEN_FEATURE_EVAS_RENDERER
@@ -2352,8 +2322,6 @@ static void _camera_client_callback_destroy(camera_cb_info_s *cb_info)
__destroy_msg_handler_thread(&cb_info->capture_cb_info);
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);
g_mutex_clear(&cb_info->preview_cb_mutex);
#ifdef TIZEN_FEATURE_EVAS_RENDERER