summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeongmo Yang <jm80.yang@samsung.com>2022-01-10 11:40:15 +0900
committerJeongmo Yang <jm80.yang@samsung.com>2022-01-10 12:22:48 +0900
commit755c1ecf7eb7aaaa147b9e2433f5e72ab7d75eac (patch)
tree0cd13151a78910e133f72940ff24d9a63f22137d
parent2bd1ae9ff63999a8016d068cef4ee00a36d82c7a (diff)
downloadcamera-755c1ecf7eb7aaaa147b9e2433f5e72ab7d75eac.tar.gz
camera-755c1ecf7eb7aaaa147b9e2433f5e72ab7d75eac.tar.bz2
camera-755c1ecf7eb7aaaa147b9e2433f5e72ab7d75eac.zip
fix up! Remove thread for preview callback when stop previewsubmit/tizen/20220110.092727accepted/tizen/unified/20220111.123039
- The thread leak is occurred with below sequence and it causes deadlock after some time. 1. Process A calls camera_start_preview(). -> create thread for preview callback 2. Process B calls camera_start_preview(). 3. Process A gets interrupted callback and the state of camera handle is changed to CAMERA_STATE_CREATED. Then, process A's preview callback thread is remained, because it is released in camera_stop_preview(), but, it's skipped by interrupt. [Version] 0.4.71 [Issue Type] Bug fix Change-Id: Ifaafb52ed3e549d3a6203754ec6fa90079893cb5 Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
-rw-r--r--packaging/capi-media-camera.spec2
-rw-r--r--src/camera.c24
2 files changed, 21 insertions, 5 deletions
diff --git a/packaging/capi-media-camera.spec b/packaging/capi-media-camera.spec
index 74a4cd2..495fc0e 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.4.70
+Version: 0.4.71
Release: 0
Group: Multimedia/API
License: Apache-2.0
diff --git a/src/camera.c b/src/camera.c
index d7e0dc0..46679c0 100644
--- a/src/camera.c
+++ b/src/camera.c
@@ -56,6 +56,10 @@ static gboolean __camera_allocate_preview_buffer(camera_h camera);
static void __camera_release_preview_buffer(camera_h camera);
static void __camera_release_tfd(int tfd[MUSE_NUM_FD]);
+static bool __create_msg_handler_thread(camera_msg_handler_info_s *handler_info,
+ int type, const char *thread_name, camera_cb_info_s *cb_info);
+static void __destroy_msg_handler_thread(camera_msg_handler_info_s *handler_info);
+
static gboolean __camera_allocate_preview_buffer(camera_h camera)
{
@@ -1599,7 +1603,7 @@ static gpointer __camera_msg_handler_func(gpointer data)
cb_info = (camera_cb_info_s *)handler_info->cb_info;
type = handler_info->type;
- CAM_LOG_INFO("t:%d start", type);
+ CAM_LOG_INFO("t:%d start[thread:%p]", type, handler_info->thread);
g_mutex_lock(&handler_info->mutex);
@@ -1649,6 +1653,11 @@ static gpointer __camera_msg_handler_func(gpointer data)
g_mutex_unlock(&cb_info->api_mutex[api]);
} else if (api == MUSE_CAMERA_CB_EVENT) {
+ if (cam_msg->event == MUSE_CAMERA_EVENT_TYPE_INTERRUPTED) {
+ CAM_LOG_WARNING("INTERRUPTED, release thread for preview cb");
+ __destroy_msg_handler_thread(&cb_info->preview_cb_info);
+ }
+
switch (cam_msg->event_class) {
case MUSE_CAMERA_EVENT_CLASS_THREAD_SUB:
__camera_client_user_callback(cb_info, cam_msg->recv_msg, cam_msg->event, cam_msg->tfd);
@@ -1706,7 +1715,7 @@ static gpointer __camera_msg_handler_func(gpointer data)
g_mutex_unlock(&handler_info->mutex);
- CAM_LOG_INFO("t:%d return", type);
+ CAM_LOG_INFO("t:%d return[thread:%p]", type, handler_info->thread);
return NULL;
}
@@ -2040,6 +2049,11 @@ static bool __create_msg_handler_thread(camera_msg_handler_info_s *handler_info,
return false;
}
+ if (handler_info->thread) {
+ CAM_LOG_WARNING("t:%d thread[%p] is already created", type, handler_info->thread);
+ return true;
+ }
+
CAM_LOG_INFO("t:%d [%s]", type, thread_name);
handler_info->type = type;
@@ -2068,7 +2082,7 @@ static bool __create_msg_handler_thread(camera_msg_handler_info_s *handler_info,
return false;
}
- CAM_LOG_INFO("t:%d done", type);
+ CAM_LOG_INFO("t:%d done[thread:%p]", type, handler_info->thread);
return true;
}
@@ -2090,7 +2104,7 @@ static void __destroy_msg_handler_thread(camera_msg_handler_info_s *handler_info
type = handler_info->type;
- CAM_LOG_INFO("t:%d thread %p", type, handler_info->thread);
+ CAM_LOG_INFO("t:%d thread[%p]", type, handler_info->thread);
g_mutex_lock(&handler_info->mutex);
g_atomic_int_set(&handler_info->running, 0);
@@ -2208,6 +2222,8 @@ 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->msg_handler_info);
__destroy_msg_handler_thread(&cb_info->capture_cb_info);