1. Fix deadlock when resource manager is disconnected 27/117627/1 accepted/tizen/common/20170309.174900 accepted/tizen/ivi/20170308.120221 accepted/tizen/mobile/20170308.120128 accepted/tizen/tv/20170308.120159 accepted/tizen/unified/20170313.080122 accepted/tizen/wearable/20170308.120211 submit/tizen/20170307.122057 submit/tizen_unified/20170310.011402 submit/tizen_unified/20170313.075707
authorJeongmo Yang <jm80.yang@samsung.com>
Mon, 6 Mar 2017 01:32:12 +0000 (10:32 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Tue, 7 Mar 2017 03:00:52 +0000 (12:00 +0900)
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 <jm80.yang@samsung.com>
packaging/libmm-camcorder.spec
src/include/mm_camcorder_resource.h
src/mm_camcorder_internal.c
src/mm_camcorder_resource.c

index b9fb802..bbfba22 100644 (file)
@@ -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
index d399a1c..b7d9c9b 100644 (file)
@@ -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);
index 97c1632..dd791b2 100644 (file)
 #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;
index cb4fd49..b54c46b 100644 (file)
@@ -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);