summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeongmo Yang <jm80.yang@samsung.com>2024-01-16 18:53:26 +0900
committerJeongmo Yang <jm80.yang@samsung.com>2024-01-25 16:32:48 +0900
commitefa3ce0fb248ed1dae502fa9beb4f804ad5140e9 (patch)
tree82c02e695a7258aaf4a5d0d45c8d2793f0c3f25d
parent1fc3247205885e18d6cc075546c41a58938e8a68 (diff)
downloadlibmm-camcorder-accepted/tizen_6.5_unified.tar.gz
libmm-camcorder-accepted/tizen_6.5_unified.tar.bz2
libmm-camcorder-accepted/tizen_6.5_unified.zip
Add defensive code for deadlock of mm-resource-manageraccepted/tizen/6.5/unified/20240401.011455tizen_6.5accepted/tizen_6.5_unified
- The deadlock can be occurred with below case. 1. Handle A : Try to stop preview -> destroy handle 2. Handle B : Create new handle and start preview while Handle A is stopping preview. Then, the resource conflict callback for Handle A is called, but it's blocked because it's already stopping preview. And the deadlock is occurred in mm-resource-manager API which is called in mm_camcorder_destroy(). [Version] 0.10.251 [Issue Type] Improvement Change-Id: Ib1b1af098cdd5c347ae73f043f4360f4c4e66ef1 Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
-rwxr-xr-xpackaging/libmm-camcorder.spec2
-rw-r--r--src/mm_camcorder_internal.c37
2 files changed, 38 insertions, 1 deletions
diff --git a/packaging/libmm-camcorder.spec b/packaging/libmm-camcorder.spec
index 71aadbf..181699f 100755
--- a/packaging/libmm-camcorder.spec
+++ b/packaging/libmm-camcorder.spec
@@ -1,6 +1,6 @@
Name: libmm-camcorder
Summary: Camera and recorder library
-Version: 0.10.250
+Version: 0.10.251
Release: 0
Group: Multimedia/Libraries
License: Apache-2.0
diff --git a/src/mm_camcorder_internal.c b/src/mm_camcorder_internal.c
index 66802b5..67b00d0 100644
--- a/src/mm_camcorder_internal.c
+++ b/src/mm_camcorder_internal.c
@@ -58,6 +58,9 @@
#ifdef _MMCAMCORDER_CAMERA_CONF_MGR_SUPPORT
#define __MMCAMCORDER_DEVICE_TYPE_STRING_LEN 1
#endif
+#ifdef _MMCAMCORDER_MM_RM_SUPPORT
+#define __MMCAMCORDER_RESOURCE_WAIT_TRY_COUNT 5
+#endif /* _MMCAMCORDER_MM_RM_SUPPORT */
#define DPM_ALLOWED 1
@@ -789,6 +792,9 @@ int _mmcamcorder_destroy(MMHandleType handle)
int state = MM_CAMCORDER_STATE_NONE;
GstElement *sink_element = NULL;
int sink_element_size = 0;
+#ifdef _MMCAMCORDER_MM_RM_SUPPORT
+ int resource_wait_try_remained = __MMCAMCORDER_RESOURCE_WAIT_TRY_COUNT;
+#endif /* _MMCAMCORDER_MM_RM_SUPPORT */
mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
@@ -842,6 +848,34 @@ int _mmcamcorder_destroy(MMHandleType handle)
/* de-initialize resource manager */
_MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
+ while (hcamcorder->is_release_cb_calling) {
+ gint64 end_time = 0;
+
+ MMCAM_LOG_WARNING("wait for resource release cb");
+
+ _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
+
+ end_time = g_get_monotonic_time() + G_TIME_SPAN_SECOND;
+ if (!_MMCAMCORDER_CMD_WAIT_UNTIL(hcamcorder, end_time)) {
+ MMCAM_LOG_WARNING("timeout, try remained[%d]", resource_wait_try_remained);
+
+ _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
+
+ if (resource_wait_try_remained > 0) {
+ resource_wait_try_remained--;
+ continue;
+ }
+
+ MMCAM_LOG_ERROR("keep going without signal...");
+ break;
+ }
+
+ MMCAM_LOG_WARNING("signal received for resource release cb[calling:%d]",
+ hcamcorder->is_release_cb_calling);
+
+ _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
+ }
+
if (hcamcorder->resource_manager != NULL) {
ret = mm_resource_manager_destroy(hcamcorder->resource_manager);
if (ret != MM_RESOURCE_MANAGER_ERROR_NONE)
@@ -3935,6 +3969,9 @@ static int __mmcamcorder_resource_release_cb(mm_resource_manager_h rm,
_MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
+ /* signal for waiting in _mmcamcorder_destroy() */
+ _MMCAMCORDER_CMD_SIGNAL(hcamcorder);
+
MMCAM_LOG_WARNING("leave");
return TRUE;