fix crash issue when dcm-service is terminated 54/56454/3 accepted/tizen/mobile/20160112.224214 accepted/tizen/tv/20160112.224231 accepted/tizen/wearable/20160112.224252 submit/tizen/20160112.092410
authorJi Yong Min <jiyong.min@samsung.com>
Fri, 8 Jan 2016 06:56:26 +0000 (15:56 +0900)
committerJi Yong Min <jiyong.min@samsung.com>
Mon, 11 Jan 2016 22:56:06 +0000 (07:56 +0900)
Change-Id: Id1a3b829cee97036e1d69dc263258e5964b436de
Signed-off-by: Jiyong Min <jiyong.min@samsung.com>
include/DcmTypes.h
packaging/dcm-service.spec
src/DcmFaceUtils.cpp
src/DcmIpcUtils.cpp
src/DcmScanSvc.cpp
svc/DcmMainSvc.cpp

index c68ab60fcfbf03dfb262631f69be1d202786cc9d..32c7d9712adb052007610b9d66b698159a115f4c 100755 (executable)
@@ -57,6 +57,7 @@ typedef enum {
 typedef enum {
        DCM_IPC_MSG_NONE,
        DCM_IPC_MSG_SERVICE_READY,
+       DCM_IPC_MSG_SERVICE_TERMINATED,
        DCM_IPC_MSG_KILL_SERVICE,
        DCM_IPC_MSG_SCAN_READY,
        DCM_IPC_MSG_SCAN_ALL,
index b9ac259f94306a0f1ddcce8fe465c335106ff76e..a3dce9ca71ce14d15fac9dc1cc8732aa7d74b8fd 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       dcm-service
 Summary:    A media DCM(Digital Contents Management) Service
-Version:    0.0.4
+Version:    0.0.5
 Release:    0
 Group:      Multimedia/Service
 License:    Apache-2.0
index 77a9f7121177b63e72f0dff8e8fa5323fc71e855..ca08c91eb2f38dcec822f87294dc7716647201fb 100755 (executable)
@@ -93,6 +93,7 @@ int DcmFaceUtils::runFaceRecognizeProcess(DcmScanItem *scan_item, DcmImageInfo *
 
        DCM_CHECK_VAL(dcm_face_handle, DCM_ERROR_INVALID_PARAMETER);
        DCM_CHECK_VAL(scan_item, DCM_ERROR_INVALID_PARAMETER);
+       DCM_CHECK_VAL(scan_item->media_uuid, DCM_ERROR_INVALID_PARAMETER);
        DCM_CHECK_VAL(image_info, DCM_ERROR_INVALID_PARAMETER);
        DCM_CHECK_VAL(image_info->pixel, DCM_ERROR_INVALID_PARAMETER);
 
index ee42874496e81d66896a7c7d42aafbe469dc43fe..12fa2488b2fef62153a4828e064b9dcb44f4b20d 100755 (executable)
@@ -158,7 +158,7 @@ int DcmIpcUtils::sendSocketMsg(DcmIpcMsgType msg_type, uid_t uid, const char *ms
        /* If message size is larget than max_size, then message is invalid */
        if (send_msg.msg_size >= DCM_IPC_MSG_MAX_SIZE) {
                dcm_error("Message size is invalid!");
-               return DCM_ERROR_INVALID_IMAGE_SIZE;
+               return DCM_ERROR_NETWORK;
        }
 
        /* Create a new TCP socket */
index 8b9f87e79f71416d8ce95aa076af7e8f2151c931..750cf7c2cb2c28ee3e2ae73f4e68b7834c424621 100755 (executable)
 #define MIME_TYPE_PNG "image/png"
 #define MIME_TYPE_BMP "image/bmp"
 
+#define DCM_SVC_SCAN_THREAD_TIMEOUT_SEC 1
+
 class DcmScanSvc {
 public:
        GMainLoop *g_scan_thread_mainloop;
        GMainContext *scan_thread_main_context;
+       gboolean g_scan_cancel;
+       GSource *scan_thread_quit_timer;
 
        /* scan all images */
        GList *scan_all_item_list;
@@ -52,6 +56,7 @@ public:
        unsigned int scan_single_curr_index;
 
        void quitScanThread();
+       int createQuitTimerScanThread();
        int getMmcState(void);
        int prepareImageList();
        int prepareImageListByPath(const char *file_path);
@@ -70,8 +75,10 @@ public:
 };
 
 namespace DcmScanCallback {
+       gboolean quitTimerAtScanThread(gpointer data);
        void freeScanItem(void *data);
        gboolean readyScanThreadIdle(gpointer data);
+       gboolean runScanThreadIdle(gpointer data);
        gboolean readMsg(GIOChannel *src, GIOCondition condition, gpointer data);
 }
 
@@ -87,6 +94,51 @@ void DcmScanSvc::quitScanThread()
        return;
 }
 
+gboolean DcmScanCallback::quitTimerAtScanThread(gpointer data)
+{
+       DcmScanSvc *dcmScanSvc = (DcmScanSvc *) data;
+
+       dcm_debug_fenter();
+
+       DCM_CHECK_FALSE(data);
+
+       if (dcmScanSvc->scan_all_curr_index != 0 || dcmScanSvc->scan_single_curr_index != 0) {
+               dcm_warn("Scan thread is working! DO NOT quit main thread!");
+               dcmScanSvc->createQuitTimerScanThread();
+       } else {
+               dcm_warn("Quit dcm-svc main loop!");
+               dcmScanSvc->quitScanThread();
+       }
+
+       dcm_debug_fleave();
+
+       return FALSE;
+}
+
+int DcmScanSvc::createQuitTimerScanThread()
+{
+       GSource *quit_timer = NULL;
+
+       dcm_debug_fenter();
+
+       if (scan_thread_quit_timer != NULL) {
+               dcm_debug("Delete old quit timer!");
+               g_source_destroy(scan_thread_quit_timer);
+               scan_thread_quit_timer = NULL;
+       }
+
+       quit_timer = g_timeout_source_new_seconds(DCM_SVC_SCAN_THREAD_TIMEOUT_SEC);
+       DCM_CHECK_VAL(quit_timer, DCM_ERROR_OUT_OF_MEMORY);
+
+       g_source_set_callback(quit_timer, DcmScanCallback::quitTimerAtScanThread, (gpointer)this, NULL);
+       g_source_attach(quit_timer, scan_thread_main_context);
+       scan_thread_quit_timer = quit_timer;
+
+       dcm_debug_fleave();
+
+       return DCM_SUCCESS;
+}
+
 int DcmScanSvc::getMmcState(void)
 {
        int err = -1;
@@ -198,6 +250,7 @@ int DcmScanSvc::initialize()
        scan_all_curr_index = 0;
        scan_single_item_list = NULL;
        scan_single_curr_index = 0;
+       g_scan_cancel = FALSE;
 
        DcmFaceUtils::initialize();
 
@@ -306,9 +359,8 @@ int DcmScanSvc::runScanProcess(DcmScanItem *scan_item)
 
                if (strcmp(scan_item->mime_type, MIME_TYPE_JPEG) == 0) {
                        image_format = DCM_IMAGE_FORMAT_RGB;
-               } else if (strcmp(scan_item->mime_type, MIME_TYPE_PNG) == 0) {
-                       image_format = DCM_IMAGE_FORMAT_RGBA;
-               } else if (strcmp(scan_item->mime_type, MIME_TYPE_BMP) == 0) {
+               } else if ((strcmp(scan_item->mime_type, MIME_TYPE_PNG) == 0) ||
+                               (strcmp(scan_item->mime_type, MIME_TYPE_BMP) == 0)) {
                        image_format = DCM_IMAGE_FORMAT_RGBA;
                } else {
                        dcm_error("Failed not supported type! (%s)", scan_item->mime_type);
@@ -355,8 +407,6 @@ int DcmScanSvc::runScanProcess(DcmScanItem *scan_item)
 int DcmScanSvc::ScanAllItems()
 {
        int ret = DCM_SUCCESS;
-       DcmScanItem *scan_item = NULL;
-       DcmDbUtils *dcmDbUtils = DcmDbUtils::getInstance();
 
        dcm_debug_fenter();
 
@@ -372,29 +422,7 @@ int DcmScanSvc::ScanAllItems()
        }
 
        /* DCM scan started */
-       unsigned int list_len = g_list_length(scan_all_item_list);
-       while (scan_all_curr_index < list_len) {
-               scan_item = (DcmScanItem *)g_list_nth_data(scan_all_item_list, scan_all_curr_index);
-               dcm_sec_debug("current index: %d, path: %s", scan_all_curr_index, scan_item->file_path);
-
-               ret = runScanProcess(scan_item);
-               if (ret != DCM_SUCCESS) {
-                       dcm_error("Failed to process scan job! err: %d", ret);
-
-                       /* If the scan item is not scanned, insert media uuid into face_scan_list */
-                       if (ret != DCM_ERROR_IMAGE_ALREADY_SCANNED) {
-                               dcmDbUtils->_dcm_svc_db_insert_face_to_face_scan_list(scan_item);
-                       }
-               }
-
-               (scan_all_curr_index)++;
-       }
-
-       dcm_warn("All images are scanned. Scan operation completed");
-
-       clearAllItemList();
-       /* Send scan complete message to main thread (if all scan operations are finished) */
-       sendCompletedMsg( NULL, DCM_IPC_PORT_DCM_RECV);
+       g_idle_add(DcmScanCallback::runScanThreadIdle, (gpointer)this);
 
        dcm_debug_fleave();
 
@@ -454,7 +482,8 @@ int DcmScanSvc::terminateScanOperations()
 {
        dcm_debug("Terminate scanning operations, and quit scan thread main loop");
 
-       quitScanThread();
+       g_scan_cancel = TRUE;
+       createQuitTimerScanThread();
 
        return DCM_SUCCESS;
 }
@@ -466,6 +495,14 @@ int DcmScanSvc::receiveMsg(DcmIpcMsg *recv_msg)
        DcmDbUtils *dcmDbUtils = DcmDbUtils::getInstance();
        DCM_CHECK_VAL(recv_msg, DCM_ERROR_INVALID_PARAMETER);
 
+       dcm_debug("msg_type: %d", recv_msg->msg_type);
+
+       if (recv_msg->msg_type == DCM_IPC_MSG_KILL_SERVICE)
+       {
+               /* Destroy scan idles, and quit scan thread main loop */
+               terminateScanOperations();
+       }
+
        ret = dcmDbUtils->_dcm_svc_db_connect(recv_msg->uid);
        if (ret != MS_MEDIA_ERR_NONE) {
                dcm_error("Failed to connect DB! err: %d", ret);
@@ -495,11 +532,6 @@ int DcmScanSvc::receiveMsg(DcmIpcMsg *recv_msg)
                        ret = DCM_ERROR_IPC_INVALID_MSG;
                }
        }
-       else if (recv_msg->msg_type == DCM_IPC_MSG_SCAN_TERMINATED)
-       {
-               /* Destroy scan idles, and quit scan thread main loop */
-               terminateScanOperations();
-       }
        else {
                dcm_error("Invalid message type!");
                ret = DCM_ERROR_IPC_INVALID_MSG;
@@ -588,6 +620,47 @@ gboolean DcmScanCallback::readyScanThreadIdle(gpointer data)
        return FALSE;
 }
 
+gboolean DcmScanCallback::runScanThreadIdle(gpointer data)
+{
+       int ret = DCM_SUCCESS;
+       DcmScanSvc *scanSvc = (DcmScanSvc *)data;
+       DcmScanItem *scan_item = NULL;
+       DcmDbUtils *dcmDbUtils = DcmDbUtils::getInstance();
+
+       dcm_debug_fenter();
+
+       DCM_CHECK_FALSE(scanSvc);
+       DCM_CHECK_FALSE(dcmDbUtils);
+
+       /* DCM scan started */
+       unsigned int list_len = g_list_length(scanSvc->scan_all_item_list);
+       if ((scanSvc->scan_all_curr_index < list_len) && !scanSvc->g_scan_cancel) {
+               scan_item = (DcmScanItem *)g_list_nth_data(scanSvc->scan_all_item_list, scanSvc->scan_all_curr_index);
+               dcm_sec_debug("current index: %d, path: %s state: %s", scanSvc->scan_all_curr_index, scan_item->file_path, (scanSvc->g_scan_cancel)?"cancel":"go");
+
+               ret = scanSvc->runScanProcess(scan_item);
+               if (ret != DCM_SUCCESS) {
+                       dcm_error("Failed to process scan job! err: %d", ret);
+
+                       /* If the scan item is not scanned, insert media uuid into face_scan_list */
+                       if (ret != DCM_ERROR_IMAGE_ALREADY_SCANNED) {
+                               dcmDbUtils->_dcm_svc_db_insert_face_to_face_scan_list(scan_item);
+                       }
+               }
+
+               (scanSvc->scan_all_curr_index)++;
+       } else {
+               dcm_warn("All images are scanned. Scan operation completed");
+               scanSvc->clearAllItemList();
+               dcm_debug_fleave();
+               return FALSE;
+       }
+
+       dcm_debug_fleave();
+
+       return TRUE;
+}
+
 void DcmScanCallback::freeScanItem(void *data)
 {
        DcmScanItem *scan_item = (DcmScanItem *) data;
index 0de091ff4ecf7febc08ef88da455c31db6b5f337..568657f840f76711e24027bbb1f83e931dbaa7b2 100755 (executable)
@@ -67,6 +67,9 @@ void DcmMainSvc::dcmServiceStartjobs(void)
 void DcmMainSvc::dcmServiceFinishjobs(void)
 {
        /* TODO: free resources for dcm-service */
+       if (DcmIpcUtils::sendSocketMsg(DCM_IPC_MSG_SERVICE_TERMINATED, 0, NULL, DCM_IPC_PORT_THUMB_RECV) != DCM_SUCCESS) {
+               dcm_error("Failed to send terminated message");
+       }
 }
 
 int DcmMainSvc::waitScanThreadReady()
@@ -167,25 +170,26 @@ gboolean DcmMainSvcCallBack::readMsg(GIOChannel *src, GIOCondition condition, gp
                        dcm_error("Failed to create scan thread! Exit main thread...");
                        return TRUE;
                }
-               
+
                dcmSvc->scan_thread_working = true;
        } else {
                dcm_debug("scan thread is already running!");
        }
 
-       if (recv_msg.msg_type == DCM_IPC_MSG_SCAN_COMPLETED) {
+       if ((recv_msg.msg_type == DCM_IPC_MSG_SCAN_COMPLETED) ||
+                       (recv_msg.msg_type == DCM_IPC_MSG_SCAN_TERMINATED)) {
                dcm_debug("Scan completed!");
                dcmSvc->scan_thread_working = false;
                dcmSvc->createQuitTimerMainLoop();
        } else if (recv_msg.msg_type == DCM_IPC_MSG_KILL_SERVICE) {
                dcm_warn("Quit dcm-svc main loop!");
-               dcmSvc->quitDcmSvcMainLoop();
+               ret = DcmIpcUtils::sendSocketMsg(DCM_IPC_MSG_KILL_SERVICE, recv_msg.uid, recv_msg.msg, DCM_IPC_PORT_SCAN_RECV);
        } else if (recv_msg.msg_type == DCM_IPC_MSG_SCAN_ALL) {
                ret = DcmIpcUtils::sendSocketMsg(DCM_IPC_MSG_SCAN_ALL, recv_msg.uid, NULL, DCM_IPC_PORT_SCAN_RECV);
        } else if (recv_msg.msg_type == DCM_IPC_MSG_SCAN_SINGLE) {
                ret = DcmIpcUtils::sendSocketMsg(DCM_IPC_MSG_SCAN_SINGLE, recv_msg.uid, recv_msg.msg, DCM_IPC_PORT_SCAN_RECV);
        } else {
-               dcm_debug("createDcmSvcReadSocket, invalid message.");          
+               dcm_debug("createDcmSvcReadSocket, invalid message.");
        }
 
        if (DcmIpcUtils::closeSocket(client_sock) < 0) {
@@ -207,7 +211,7 @@ gboolean DcmMainSvcCallBack::quitTimerAtMainLoop(gpointer data)
                dcm_warn("Scan thread is working! DO NOT quit main thread!");
        } else {
                dcm_warn("Quit dcm-svc main loop!");
-               DcmIpcUtils::sendSocketMsg(DCM_IPC_MSG_KILL_SERVICE, 0, NULL, DCM_IPC_PORT_DCM_RECV);
+               dcmSvcApp->quitDcmSvcMainLoop();
        }
 
        dcm_debug_fleave();