diff options
author | Jeongmo Yang <jm80.yang@samsung.com> | 2017-03-31 16:58:37 +0900 |
---|---|---|
committer | Jeongmo Yang <jm80.yang@samsung.com> | 2017-03-31 17:00:48 +0900 |
commit | 46d1f8b00ca0d6c9774fb0b4ef0ccf40b59ff32e (patch) | |
tree | b6802bce5f3e65ffa9370474efc13a733777dc4e | |
parent | 4cb3329c10a6cac78905551230de59cd6a66c5bf (diff) | |
download | camera-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.spec | 4 | ||||
-rw-r--r-- | src/camera.c | 48 |
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; |