From 903a86fa213b155058fcf6dc8f729f9502ac8498 Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Mon, 6 Mar 2017 10:32:12 +0900 Subject: [PATCH] 1. Fix deadlock when resource manager is disconnected 2. Recover resource manager connection after disconnected [Version] 0.10.111 [Profile] Common [Issue Type] Update/Bug fix [Dependency module] N/A [Test] [M(T) - Boot=(OK), sdb=(OK), Home=(OK), Touch=(OK), Version=tizen-3.0-mobile_20170302.1] Change-Id: I839c9fb4f8877d9f3dc8856619a474658e2e3fc2 Signed-off-by: Jeongmo Yang --- packaging/libmm-camcorder.spec | 2 +- src/include/mm_camcorder_resource.h | 3 +++ src/mm_camcorder_internal.c | 51 +++++++++++++++++++------------------ src/mm_camcorder_resource.c | 38 +++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 26 deletions(-) diff --git a/packaging/libmm-camcorder.spec b/packaging/libmm-camcorder.spec index b9fb802..bbfba22 100644 --- 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.110 +Version: 0.10.111 Release: 0 Group: Multimedia/Libraries License: Apache-2.0 diff --git a/src/include/mm_camcorder_resource.h b/src/include/mm_camcorder_resource.h index d399a1c..b7d9c9b 100644 --- a/src/include/mm_camcorder_resource.h +++ b/src/include/mm_camcorder_resource.h @@ -28,6 +28,8 @@ extern "C" { #endif +#define __MMCAMCORDER_RESOURCE_WAIT_TIME 3 + typedef enum { MM_CAMCORDER_RESOURCE_TYPE_CAMERA, MM_CAMCORDER_RESOURCE_TYPE_VIDEO_OVERLAY, @@ -45,6 +47,7 @@ typedef struct { } MMCamcorderResourceManager; int _mmcamcorder_resource_manager_init(MMCamcorderResourceManager *resource_manager, void *user_data); +int _mmcamcorder_resource_wait_for_connection(MMCamcorderResourceManager *resource_manager, void *hcamcorder); int _mmcamcorder_resource_create_resource_set(MMCamcorderResourceManager *resource_manager); int _mmcamcorder_resource_manager_prepare(MMCamcorderResourceManager *resource_manager, MMCamcorderResourceType resource_type); int _mmcamcorder_resource_manager_acquire(MMCamcorderResourceManager *resource_manager); diff --git a/src/mm_camcorder_internal.c b/src/mm_camcorder_internal.c index 97c1632..dd791b2 100644 --- a/src/mm_camcorder_internal.c +++ b/src/mm_camcorder_internal.c @@ -61,11 +61,6 @@ #define DPM_ALLOWED 1 #define DPM_DISALLOWED 0 -#ifdef _MMCAMCORDER_MURPHY_SUPPORT -#define __MMCAMCORDER_RESOURCE_WAIT_TIME 3 -#endif /* _MMCAMCORDER_MURPHY_SUPPORT */ - - /*--------------------------------------------------------------------------------------- | LOCAL FUNCTION PROTOTYPES: | ---------------------------------------------------------------------------------------*/ @@ -493,27 +488,11 @@ int _mmcamcorder_create(MMHandleType *handle, MMCamPreset *info) #ifdef _MMCAMCORDER_MURPHY_SUPPORT if (info->videodev_type != MM_VIDEO_DEVICE_NONE) { - _MMCAMCORDER_LOCK_RESOURCE(hcamcorder); - - if (hcamcorder->resource_manager.is_connected == FALSE) { - gint64 end_time = 0; - - /* wait for resource manager connected */ - _mmcam_dbg_log("resource manager is not connected. wait for signal..."); - - end_time = g_get_monotonic_time() + (__MMCAMCORDER_RESOURCE_WAIT_TIME * G_TIME_SPAN_SECOND); - - if (_MMCAMCORDER_RESOURCE_WAIT_UNTIL(hcamcorder, end_time)) { - _mmcam_dbg_warn("signal received"); - } else { - _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder); - _mmcam_dbg_err("timeout"); - ret = MM_ERROR_RESOURCE_INTERNAL; - goto _ERR_DEFAULT_VALUE_INIT; - } + ret = _mmcamcorder_resource_wait_for_connection(&hcamcorder->resource_manager, (void *)hcamcorder); + if (ret != MM_ERROR_NONE) { + _mmcam_dbg_err("failed to connect resource manager"); + goto _ERR_DEFAULT_VALUE_INIT; } - - _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder); } #endif /* _MMCAMCORDER_MURPHY_SUPPORT */ @@ -1079,6 +1058,28 @@ int _mmcamcorder_realize(MMHandleType handle) } #ifdef _MMCAMCORDER_MURPHY_SUPPORT + /* check connection */ + if (hcamcorder->resource_manager.is_connected == FALSE) { + _mmcam_dbg_warn("resource manager disconnected before, try to reconnect"); + + /* release remained resource */ + _mmcamcorder_resource_manager_deinit(&hcamcorder->resource_manager); + + /* init resource manager and wait for connection */ + ret = _mmcamcorder_resource_manager_init(&hcamcorder->resource_manager, (void *)hcamcorder); + if (ret != MM_ERROR_NONE) { + _mmcam_dbg_err("failed to initialize resource manager"); + ret = MM_ERROR_CAMCORDER_INTERNAL; + goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK; + } + + ret = _mmcamcorder_resource_wait_for_connection(&hcamcorder->resource_manager, (void *)hcamcorder); + if (ret != MM_ERROR_NONE) { + _mmcam_dbg_err("failed to connect resource manager"); + goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK; + } + } + ret = _mmcamcorder_resource_create_resource_set(&hcamcorder->resource_manager); if (ret != MM_ERROR_NONE) { goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK; diff --git a/src/mm_camcorder_resource.c b/src/mm_camcorder_resource.c index cb4fd49..b54c46b 100644 --- a/src/mm_camcorder_resource.c +++ b/src/mm_camcorder_resource.c @@ -125,6 +125,8 @@ static void __mmcamcorder_resource_state_callback(mrp_res_context_t *context, mr camcorder->resource_manager.is_connected = FALSE; } + _MMCAMCORDER_UNLOCK_RESOURCE(camcorder); + _MMCAMCORDER_LOCK_ASM(camcorder); /* set value to inform a status is changed by resource manaer */ @@ -137,6 +139,8 @@ static void __mmcamcorder_resource_state_callback(mrp_res_context_t *context, mr camcorder->state_change_by_system = _MMCAMCORDER_STATE_CHANGE_NORMAL; _MMCAMCORDER_UNLOCK_ASM(camcorder); + + _MMCAMCORDER_LOCK_RESOURCE(camcorder); break; } @@ -401,6 +405,40 @@ int _mmcamcorder_resource_manager_init(MMCamcorderResourceManager *resource_mana return MM_ERROR_NONE; } + +int _mmcamcorder_resource_wait_for_connection(MMCamcorderResourceManager *resource_manager, void *hcamcorder) +{ + int ret = MM_ERROR_NONE; + + mmf_return_val_if_fail(resource_manager && hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED); + + _MMCAMCORDER_LOCK_RESOURCE(hcamcorder); + + if (resource_manager->is_connected == FALSE) { + gint64 end_time = 0; + + /* wait for resource manager connected */ + _mmcam_dbg_warn("not connected. wait for signal..."); + + end_time = g_get_monotonic_time() + (__MMCAMCORDER_RESOURCE_WAIT_TIME * G_TIME_SPAN_SECOND); + + if (_MMCAMCORDER_RESOURCE_WAIT_UNTIL(hcamcorder, end_time)) { + _mmcam_dbg_warn("signal received"); + ret = MM_ERROR_NONE; + } else { + _mmcam_dbg_err("connection timeout"); + ret = MM_ERROR_RESOURCE_INTERNAL; + } + } else { + _mmcam_dbg_warn("already connected"); + } + + _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder); + + return ret; +} + + int _mmcamcorder_resource_manager_prepare(MMCamcorderResourceManager *resource_manager, MMCamcorderResourceType resource_type) { MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager); -- 2.7.4