Fix deadlock in camera_dispatcher_unset_preview_cb 39/159139/1 accepted/tizen/unified/20171108.161107 submit/tizen/20171108.005543
authorJeongmo Yang <jm80.yang@samsung.com>
Tue, 7 Nov 2017 06:45:21 +0000 (15:45 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Tue, 7 Nov 2017 06:45:21 +0000 (15:45 +0900)
The mutex lock is used in camera_dispatcher_unset_preview_cb
and same one is used in preview_callback function.
When preview buffer is come, preview callback function locks mutex
and wait for returned buffer.
But at that time, deadlock could be occurred if camera_dispatcher_unset_preview_cb is also called.
Because muse camera's socket handing thread is only one
and camera_dispatcher_unset_preview_cb tries to lock mutex while preempting handling thread,
so return buffer message could not be handled.

This patch makes return buffer message could be handled while some APIs are calling.

[Version] 0.3.7
[Profile] Common
[Issue Type] Bug fix
[Dependency module] N/A
[Test] [M(T) - Boot=(OK), sdb=(OK), Home=(OK), Touch=(OK), Version=tizen-4.0-unified_20171106.1]

Change-Id: Iacb6c5125db0267795dd30c74555f69cc6ac3c89
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
muse/src/muse_camera_dispatcher.c
packaging/mmsvc-camera.spec

index 8ca6d80cb120550c9c139fb4625ea311eff899da..3e124855142187b32b0c51bb955ab0210a2bde14 100644 (file)
@@ -1334,6 +1334,29 @@ static void __camera_task_process_job(muse_camera_handle_s *muse_camera, muse_ca
                ret = legacy_camera_attr_set_hdr_mode(muse_camera->camera_handle, \
                        (camera_attr_hdr_mode_e)job->value);
                break;
+       case MUSE_CAMERA_API_SET_PREVIEW_CB:
+               ret = legacy_camera_set_preview_cb(muse_camera->camera_handle, \
+                       (camera_preview_cb)_camera_dispatcher_preview_cb,
+                       (void *)muse_camera->module);
+
+               if (ret == CAMERA_ERROR_NONE)
+                       SET_PREVIEW_CB_TYPE(muse_camera, PREVIEW_CB_TYPE_USER);
+               break;
+       case MUSE_CAMERA_API_UNSET_PREVIEW_CB:
+               UNSET_PREVIEW_CB_TYPE(muse_camera, PREVIEW_CB_TYPE_USER);
+               if (CHECK_PREVIEW_CB(muse_camera, PREVIEW_CB_TYPE_EVAS))
+                       LOGW("Preview callback for evas surface is remained.");
+               else
+                       ret = legacy_camera_unset_preview_cb(muse_camera->camera_handle);
+               break;
+       case MUSE_CAMERA_API_SET_MEDIA_PACKET_PREVIEW_CB:
+               ret = legacy_camera_set_media_packet_preview_cb(muse_camera->camera_handle,
+                       (camera_preview_cb)_camera_dispatcher_preview_cb,
+                       (void *)muse_camera->module);
+               break;
+       case MUSE_CAMERA_API_UNSET_MEDIA_PACKET_PREVIEW_CB:
+               ret = legacy_camera_unset_media_packet_preview_cb(muse_camera->camera_handle);
+               break;
        default:
                LOGE("unhandled task - api %d", job->api);
                goto _PROCESS_DONE;
@@ -2460,91 +2483,56 @@ int camera_dispatcher_get_flash_state(muse_module_h module)
 
 int camera_dispatcher_set_preview_cb(muse_module_h module)
 {
-       int ret = CAMERA_ERROR_NONE;
        muse_camera_handle_s *muse_camera = NULL;
-       muse_camera_api_e api = MUSE_CAMERA_API_SET_PREVIEW_CB;
-       muse_camera_api_class_e class = MUSE_CAMERA_API_CLASS_IMMEDIATE;
 
        muse_camera = (muse_camera_handle_s *)muse_server_ipc_get_handle(module);
 
        LOGD("handle : %p", muse_camera);
 
-       ret = legacy_camera_set_preview_cb(muse_camera->camera_handle,
-               (camera_preview_cb)_camera_dispatcher_preview_cb,
-               (void *)module);
-
-       if (ret == CAMERA_ERROR_NONE)
-               SET_PREVIEW_CB_TYPE(muse_camera, PREVIEW_CB_TYPE_USER);
-
-       LOGD("ret : 0x%x", ret);
-
-       muse_camera_msg_return(api, class, ret, module);
+       _camera_task_add_job(muse_camera, MUSE_CAMERA_API_SET_PREVIEW_CB,
+               MUSE_CAMERA_API_CLASS_IMMEDIATE, 0);
 
        return MUSE_CAMERA_ERROR_NONE;
 }
 
 int camera_dispatcher_unset_preview_cb(muse_module_h module)
 {
-       int ret = CAMERA_ERROR_NONE;
        muse_camera_handle_s *muse_camera = NULL;
-       muse_camera_api_e api = MUSE_CAMERA_API_UNSET_PREVIEW_CB;
-       muse_camera_api_class_e class = MUSE_CAMERA_API_CLASS_IMMEDIATE;
 
        muse_camera = (muse_camera_handle_s *)muse_server_ipc_get_handle(module);
 
        LOGD("handle : %p", muse_camera);
 
-       UNSET_PREVIEW_CB_TYPE(muse_camera, PREVIEW_CB_TYPE_USER);
-       if (CHECK_PREVIEW_CB(muse_camera, PREVIEW_CB_TYPE_EVAS))
-               LOGD("Preview callback for evas surface is remained.");
-       else
-               ret = legacy_camera_unset_preview_cb(muse_camera->camera_handle);
-
-       LOGD("ret : 0x%x", ret);
-
-       muse_camera_msg_return(api, class, ret, module);
+       _camera_task_add_job(muse_camera, MUSE_CAMERA_API_UNSET_PREVIEW_CB,
+               MUSE_CAMERA_API_CLASS_IMMEDIATE, 0);
 
        return MUSE_CAMERA_ERROR_NONE;
 }
 
 int camera_dispatcher_set_media_packet_preview_cb(muse_module_h module)
 {
-       int ret = CAMERA_ERROR_NONE;
        muse_camera_handle_s *muse_camera = NULL;
-       muse_camera_api_e api = MUSE_CAMERA_API_SET_MEDIA_PACKET_PREVIEW_CB;
-       muse_camera_api_class_e class = MUSE_CAMERA_API_CLASS_IMMEDIATE;
 
        muse_camera = (muse_camera_handle_s *)muse_server_ipc_get_handle(module);
 
        LOGD("handle : %p", muse_camera);
 
-       ret = legacy_camera_set_media_packet_preview_cb(muse_camera->camera_handle,
-               (camera_preview_cb)_camera_dispatcher_preview_cb,
-               (void *)module);
-
-       LOGD("ret : 0x%x", ret);
-
-       muse_camera_msg_return(api, class, ret, module);
+       _camera_task_add_job(muse_camera, MUSE_CAMERA_API_SET_MEDIA_PACKET_PREVIEW_CB,
+               MUSE_CAMERA_API_CLASS_IMMEDIATE, 0);
 
        return MUSE_CAMERA_ERROR_NONE;
 }
 
 int camera_dispatcher_unset_media_packet_preview_cb(muse_module_h module)
 {
-       int ret = CAMERA_ERROR_NONE;
        muse_camera_handle_s *muse_camera = NULL;
-       muse_camera_api_e api = MUSE_CAMERA_API_UNSET_MEDIA_PACKET_PREVIEW_CB;
-       muse_camera_api_class_e class = MUSE_CAMERA_API_CLASS_IMMEDIATE;
 
        muse_camera = (muse_camera_handle_s *)muse_server_ipc_get_handle(module);
 
        LOGD("handle : %p", muse_camera);
 
-       ret = legacy_camera_unset_media_packet_preview_cb(muse_camera->camera_handle);
-
-       LOGD("ret : 0x%x", ret);
-
-       muse_camera_msg_return(api, class, ret, module);
+       _camera_task_add_job(muse_camera, MUSE_CAMERA_API_UNSET_MEDIA_PACKET_PREVIEW_CB,
+               MUSE_CAMERA_API_CLASS_IMMEDIATE, 0);
 
        return MUSE_CAMERA_ERROR_NONE;
 }
index c7ca014a878c185c03c74b586db94147bc454906..cdb307066fc57ccf5ff18b4a4d0712976a409719 100644 (file)
@@ -1,6 +1,6 @@
 Name:       mmsvc-camera
 Summary:    A Camera module for muse server
-Version:    0.3.6
+Version:    0.3.7
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0