summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeongmo Yang <jm80.yang@samsung.com>2017-03-31 16:58:37 +0900
committerJeongmo Yang <jm80.yang@samsung.com>2017-03-31 17:00:48 +0900
commit46d1f8b00ca0d6c9774fb0b4ef0ccf40b59ff32e (patch)
treeb6802bce5f3e65ffa9370474efc13a733777dc4e
parent4cb3329c10a6cac78905551230de59cd6a66c5bf (diff)
downloadcamera-46d1f8b00ca0d6c9774fb0b4ef0ccf40b59ff32e.tar.gz
camera-46d1f8b00ca0d6c9774fb0b4ef0ccf40b59ff32e.tar.bz2
camera-46d1f8b00ca0d6c9774fb0b4ef0ccf40b59ff32e.zip
Avoid double free for idle event
Sometimes, the idle callback is called although g_idle_remove_by_data returned true, then double free could be occurred. So, update code to avoid it like below. - remove g_idle_remove_by_data and idle callback will be always called - remove free code for idle callback data in _recorder_remove_idle_event_all, then it will be freed in idle callback - change function name from _recorder_remove_idle_event_all to _recorder_deactivate_idle_event_all [Version] 0.2.100 [Profile] Common [Issue Type] Update [Dependency module] N/A [Test] [M(T) - Boot=(OK), sdb=(OK), Home=(OK), Touch=(OK), Version=tizen-3.0-mobile_20170321.3] Change-Id: I352e6841f3fc1a48132faa9d0c0a90e126a211f5 Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
-rw-r--r--packaging/capi-media-camera.spec4
-rw-r--r--src/camera.c48
2 files changed, 19 insertions, 33 deletions
diff --git a/packaging/capi-media-camera.spec b/packaging/capi-media-camera.spec
index 00dc4d9..e21a01c 100644
--- a/packaging/capi-media-camera.spec
+++ b/packaging/capi-media-camera.spec
@@ -1,7 +1,7 @@
Name: capi-media-camera
Summary: A Camera API
-Version: 0.2.99
-Release: 1
+Version: 0.2.100
+Release: 0
Group: Multimedia/API
License: Apache-2.0
Source0: %{name}-%{version}.tar.gz
diff --git a/src/camera.c b/src/camera.c
index 7d50534..4e83dec 100644
--- a/src/camera.c
+++ b/src/camera.c
@@ -1578,7 +1578,7 @@ static bool _camera_idle_event_callback(void *data)
cb_info = cam_idle_event->cb_info;
if (cb_info == NULL) {
- LOGW("camera cb_info is NULL. event %d", cam_idle_event->event);
+ LOGW("camera cb_info is NULL. event %p %d", cam_idle_event, cam_idle_event->event);
goto IDLE_EVENT_CALLBACK_DONE;
}
@@ -1592,7 +1592,7 @@ static bool _camera_idle_event_callback(void *data)
g_mutex_unlock(&cb_info->idle_event_mutex);
/* user callback */
- _camera_client_user_callback(cam_idle_event->cb_info, cam_idle_event->recv_msg, cam_idle_event->event);
+ _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);
@@ -1736,10 +1736,9 @@ static void *_camera_msg_handler_func(gpointer data)
}
-static void _camera_remove_idle_event_all(camera_cb_info_s *cb_info)
+static void _camera_deactivate_idle_event_all(camera_cb_info_s *cb_info)
{
camera_idle_event_s *cam_idle_event = NULL;
- gboolean ret = TRUE;
GList *list = NULL;
gint64 end_time = 0;
@@ -1767,40 +1766,27 @@ static void _camera_remove_idle_event_all(camera_cb_info_s *cb_info)
continue;
}
- if (g_mutex_trylock(&cam_idle_event->event_mutex)) {
- ret = g_idle_remove_by_data(cam_idle_event);
+ if (!g_mutex_trylock(&cam_idle_event->event_mutex)) {
+ LOGW("lock failed, %p event is calling now", cam_idle_event);
- LOGD("remove idle event [%p], ret[%d]", cam_idle_event, ret);
+ end_time = g_get_monotonic_time() + G_TIME_SPAN_MILLISECOND * 100;
- if (!ret) {
- cam_idle_event->cb_info = NULL;
- LOGW("idle event %p will be called later", cam_idle_event);
- }
-
- 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);
-
- if (ret) {
- g_mutex_clear(&cam_idle_event->event_mutex);
-
- g_free(cam_idle_event);
- cam_idle_event = NULL;
-
- LOGD("remove idle event done");
- }
+ 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("event lock failed. it's being called...");
+ LOGW("set NULL cb_info for event %p %d, it will be freed on idle callback",
+ cam_idle_event, cam_idle_event->event);
- end_time = g_get_monotonic_time() + G_TIME_SPAN_MILLISECOND * 100;
+ cam_idle_event->cb_info = NULL;
+
+ cb_info->idle_event_list = g_list_remove(cb_info->idle_event_list, (gpointer)cam_idle_event);
- if (g_cond_wait_until(&cb_info->idle_event_cond, &cb_info->idle_event_mutex, end_time))
- LOGW("signal received");
- else
- LOGW("timeout");
+ g_mutex_unlock(&cam_idle_event->event_mutex);
}
g_list_free(cb_info->idle_event_list);
@@ -2679,7 +2665,7 @@ int camera_destroy(camera_h camera)
LOGW("server disconnected. release resource without send message.");
if (ret == CAMERA_ERROR_NONE) {
- _camera_remove_idle_event_all(pc->cb_info);
+ _camera_deactivate_idle_event_all(pc->cb_info);
_camera_client_callback_destroy(pc->cb_info);
pc->cb_info = NULL;