Add thumb-dcm thread to run DCM service, but disabled 12/48912/6 accepted/tizen/mobile/20151012.040632 accepted/tizen/tv/20151012.040649 accepted/tizen/wearable/20151012.040700 submit/tizen/20151012.020617
authorJi Yong Min <jiyong.min@samsung.com>
Thu, 1 Oct 2015 10:44:46 +0000 (19:44 +0900)
committerJi Yong Min <jiyong.min@samsung.com>
Fri, 2 Oct 2015 07:00:45 +0000 (16:00 +0900)
DCM service will work after change "ENABLE_DCM" to "true" in CMakeLists.txt

Change-Id: Iaa6c854860836452c4c68c76fbc693e53a0311c8

CMakeLists.txt [changed mode: 0644->0755]
server/CMakeLists.txt
server/include/thumb-server-dcm.h [new file with mode: 0755]
server/thumb-server-dcm.c [new file with mode: 0755]
server/thumb-server-internal.c
server/thumb-server.c

old mode 100644 (file)
new mode 100755 (executable)
index 7eb108f..6cfe38d
@@ -2,6 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
 PROJECT(media-thumbnail C)
 SET(VERSION_MAJOR 1)
 SET(VERSION "${VERSION_MAJOR}.0.0")
+SET(ENABLE_DCM "false")
 
 SET(MEDIATHUMB-LIB "media-thumbnail")
 SET(MEDIAHASH-LIB "media-hash")
@@ -62,6 +63,9 @@ ADD_DEFINITIONS("-DPACKAGE_NAME=\"${PKGNAME}\"")
 ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
 ADD_DEFINITIONS("-D_GNU_SOURCE")
 #ADD_DEFINITIONS("-D_PERFORMANCE_CHECK_")
+IF("${ENABLE_DCM}" STREQUAL "true")
+ADD_DEFINITIONS("-D_SUPPORT_DCM")
+ENDIF("${ENABLE_DCM}" STREQUAL "true")
 
 SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--hash-style=both")
 CONFIGURE_FILE(media-thumbnail.pc.in media-thumbnail.pc @ONLY)
index 268e223..fdeaab7 100755 (executable)
@@ -1,8 +1,17 @@
+IF("${ENABLE_DCM}" STREQUAL "true")
+SET(THUMB-SERVER
+        ../src/util/media-thumb-db.c
+           ../src/media-thumb-internal.c
+           thumb-server.c
+           thumb-server-internal.c
+           thumb-server-dcm.c)
+ELSE("${ENABLE_DCM}" STREQUAL "true")
 SET(THUMB-SERVER
         ../src/util/media-thumb-db.c
            ../src/media-thumb-internal.c
            thumb-server.c
            thumb-server-internal.c)
+ENDIF("${ENABLE_DCM}" STREQUAL "true")
 
 INCLUDE(FindPkgConfig)
        pkg_check_modules(pkgs REQUIRED glib-2.0 gthread-2.0 dlog mm-fileinfo aul libexif ecore-evas evas mmutil-imgp mmutil-jpeg libmedia-utils vconf libtzplatform-config)
diff --git a/server/include/thumb-server-dcm.h b/server/include/thumb-server-dcm.h
new file mode 100755 (executable)
index 0000000..9d41c10
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * media-thumbnail-server
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Lei Zhang <lei527.zhang@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _THUMB_SERVER_DCM_H_
+#define _THUMB_SERVER_DCM_H_
+
+#include <glib.h>
+#include "media-thumb-ipc.h"
+
+typedef enum {
+       THUMB_SERVER_DCM_MSG_NONE = 0,
+       THUMB_SERVER_DCM_MSG_SERVER_READY,
+       THUMB_SERVER_DCM_MSG_STOP,
+       THUMB_SERVER_DCM_MSG_SCAN_READY,  /* NOT_USED */
+       THUMB_SERVER_DCM_MSG_SCAN_ALL,
+       THUMB_SERVER_DCM_MSG_SCAN_SINGLE,
+       THUMB_SERVER_DCM_MSG_MAX,
+} thumb_server_dcm_ipc_msg_type_e;
+
+typedef enum {
+       THUMB_SERVER_DCM_PORT_DCM_RECV,
+       THUMB_SERVER_DCM_PORT_THUMB_RECV,
+       THUMB_SERVER_DCM_PORT_DCM_SVC_APP_RECV,
+       THUMB_SERVER_DCM_PORT_MAX,
+} thumb_server_dcm_port_type_e;
+
+typedef struct {
+       thumb_server_dcm_ipc_msg_type_e msg_type;
+       uid_t uid;
+       size_t msg_size; /*this is size of message below and this does not include the terminationg null byte ('\0'). */
+       char msg[MAX_PATH_SIZE];
+} thumb_server_dcm_ipc_msg_s;
+
+gboolean _thumb_server_dcm_thread(void *data);
+int _thumb_server_dcm_send_msg(thumb_server_dcm_ipc_msg_type_e msg_type, uid_t uid, const char *msg, thumb_server_dcm_port_type_e port);
+void _thumb_server_dcm_quit_main_loop();
+int thumb_server_dcm_get_server_pid();
+void thumb_server_dcm_reset_server_status();
+
+#endif /*_THUMB_SERVER_DCM_H_*/
diff --git a/server/thumb-server-dcm.c b/server/thumb-server-dcm.c
new file mode 100755 (executable)
index 0000000..27b274d
--- /dev/null
@@ -0,0 +1,621 @@
+/*
+ * media-thumbnail-server
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Lei Zhang <lei527.zhang@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <glib.h>
+#include <sys/syscall.h>
+#include <sys/stat.h>
+#include <aul.h>
+#include <fcntl.h>
+#include <dirent.h>
+
+#include "media-thumb-ipc.h"
+#include "media-thumb-db.h"
+#include "media-thumb-util.h"
+#include "media-thumb-debug.h"
+
+#include "thumb-server-dcm.h"
+
+#ifdef _SUPPORT_DCM
+#define dcm_retvm_if(expr, val, fmt, arg...) do { \
+       if(expr) { \
+               thumb_err(fmt, ##arg); \
+               thumb_err("(%s) -> %s() return", #expr, __FUNCTION__); \
+               return (val); \
+       } \
+} while (0)
+
+#define DCM_CHECK_VAL(expr, val)               dcm_retvm_if(!(expr), val, "Invalid parameter, return ERROR code!")
+
+#define DCM_SVC_NAME "dcm-svc"
+#define DCM_SVC_EXEC_NAME "/usr/bin/dcm-svc"
+
+static GMainLoop *g_dcm_thread_mainloop;
+static bool b_dcm_svc_launched;
+static int g_dcm_timer_id = 0;
+static int g_dcm_server_pid = 0;
+
+static char DCM_IPC_PATH[3][100] =
+                       {"/var/run/media-server/media_ipc_thumbdcm_dcmrecv",
+                        "/var/run/media-server/media_ipc_thumbdcm_thumbrecv",
+                        "/var/run/media-server/dcm_ipc_thumbserver_comm_recv"};
+
+static gboolean g_folk_dcm_server = FALSE;
+static gboolean g_dcm_server_extracting = FALSE;
+static gboolean g_shutdowning_dcm_server = FALSE;
+static int g_dcm_communicate_sock = 0;
+static thumb_server_dcm_ipc_msg_s last_msg;
+
+static int __thumb_server_dcm_create_socket(int *socket_fd, thumb_server_dcm_port_type_e port);
+static int __thumb_server_dcm_process_recv_msg(thumb_server_dcm_ipc_msg_s *recv_msg);
+void __thumb_server_dcm_create_timer(int id);
+
+gboolean __thumb_server_dcm_agent_timer()
+{
+       if (g_dcm_server_extracting) {
+               thumb_dbg("Timer is called.. But dcm-svc[%d] is busy.. so timer is recreated", g_dcm_server_pid);
+
+               __thumb_server_dcm_create_timer(g_dcm_timer_id);
+               return FALSE;
+       }
+
+       g_dcm_timer_id = 0;
+       thumb_dbg("Timer is called.. Now killing dcm-svc[%d]", g_dcm_server_pid);
+
+       if (g_dcm_server_pid > 0) {
+               /* Command Kill to thumbnail server */
+               g_shutdowning_dcm_server = TRUE;
+               if (!_thumb_server_dcm_send_msg(THUMB_SERVER_DCM_MSG_STOP, 0, NULL, THUMB_SERVER_DCM_PORT_DCM_SVC_APP_RECV)) {
+                       thumb_err("_thumb_server_dcm_send_msg is failed");
+                       g_shutdowning_dcm_server = FALSE;
+               }
+               usleep(200000);
+               g_dcm_communicate_sock = 0;
+       } else {
+               thumb_err("g_server_pid is %d. Maybe there's problem in thumbnail-server", g_dcm_server_pid);
+       }
+
+       return FALSE;
+}
+
+void __thumb_server_dcm_create_timer(int id)
+{
+       if (id > 0)
+               g_source_destroy(g_main_context_find_source_by_id(g_main_context_get_thread_default(), id));
+
+       GSource *timer_src = g_timeout_source_new_seconds(MS_TIMEOUT_SEC_20);
+       g_source_set_callback (timer_src, __thumb_server_dcm_agent_timer, NULL, NULL);
+       g_dcm_timer_id = g_source_attach (timer_src, g_main_context_get_thread_default());
+
+}
+
+int __thumb_strcopy(char *res, const int size, const char *pattern, const char *str1)
+{
+       int len = 0;
+       int real_size = size;
+
+       if (!res || !pattern || !str1) {
+               thumb_err("parameta is invalid");
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       if (real_size < strlen(str1)) {
+               thumb_err("size is wrong");
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       len = snprintf(res, real_size, pattern, str1);
+       if (len < 0) {
+               thumb_err("snprintf failed");
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       res[len] = '\0';
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+/* This checks if thumbnail server is running */
+bool __thumb_server_dcm_check_process()
+{
+       DIR *pdir;
+       struct dirent pinfo;
+       struct dirent *result = NULL;
+       bool ret = FALSE;
+
+       pdir = opendir("/proc");
+       if (pdir == NULL) {
+               thumb_err("err: NO_DIR");
+               return 0;
+       }
+
+       while (!readdir_r(pdir, &pinfo, &result)) {
+               if (result == NULL)
+                       break;
+
+               if (pinfo.d_type != 4 || pinfo.d_name[0] == '.'
+                   || pinfo.d_name[0] > 57)
+                       continue;
+
+               FILE *fp;
+               char buff[128];
+               char path[128];
+
+               __thumb_strcopy(path, sizeof(path), "/proc/%s/status", pinfo.d_name);
+               fp = fopen(path, "rt");
+               if (fp) {
+                       if (fgets(buff, 128, fp) == NULL)
+                               thumb_err("fgets failed");
+                       fclose(fp);
+
+                       if (strstr(buff, DCM_SVC_NAME)) {
+                               thumb_err("%s proc is already running", buff);
+                               ret = TRUE;
+                               break;
+                       }
+               } else {
+                       thumb_err("Can't read file [%s]", path);
+               }
+       }
+
+       closedir(pdir);
+
+       return ret;
+}
+
+/*gboolean __thumb_server_dcm_agent_recv_msg_from_server()
+{
+       int recv_msg_size = 0;
+       thumb_server_dcm_ipc_msg_s recv_msg;
+
+       if (g_dcm_communicate_sock <= 0) {
+               if (__thumb_server_dcm_create_socket(&g_dcm_communicate_sock, THUMB_SERVER_DCM_PORT_DCM_SVC_APP_RECV) < 0) {
+                       thumb_err("ms_ipc_create_server_socket failed");
+                       return FALSE;
+               }
+       }
+
+       if ((recv_msg_size = read(g_dcm_communicate_sock, &recv_msg, sizeof(thumb_server_dcm_ipc_msg_s))) < 0) {
+               if (errno == EWOULDBLOCK) {
+                       thumb_err("Timeout. Can't try any more");
+                       return MEDIA_THUMB_ERROR_NETWORK;
+               } else {
+                       thumb_err("recv failed : %s", strerror(errno));
+                       return MEDIA_THUMB_ERROR_NETWORK;
+               }
+       }
+       thumb_dbg_slog("[receive msg] type: %d, msg: %s, msg_size: %d", recv_msg.msg_type, recv_msg.msg, recv_msg.msg_size);
+
+       if (!(recv_msg.msg_type >= 0 && recv_msg.msg_type < THUMB_SERVER_DCM_MSG_MAX)) {
+               thumb_err("IPC message is wrong!");
+               return  MEDIA_THUMB_ERROR_NETWORK;
+       }
+
+       if (recv_msg.msg_type == THUMB_SERVER_DCM_MSG_SERVER_READY) {
+               thumb_dbg("DcmSvc server is ready");
+               __thumb_server_dcm_process_recv_msg(&last_msg);
+       }
+
+       return TRUE;
+}*/
+
+gboolean __thumb_server_dcm_agent_execute_server()
+{
+       thumb_dbg("Exec DCM_SVC: start");
+
+       int pid;
+       pid = fork();
+
+       if (pid < 0) {
+               return FALSE;
+       } else if (pid == 0) {
+               execl(DCM_SVC_EXEC_NAME, DCM_SVC_NAME, NULL);
+       } else {
+               thumb_dbg("Child process is %d", pid);
+               g_folk_dcm_server = TRUE;
+       }
+
+       g_dcm_server_pid = pid;
+
+       if (g_dcm_communicate_sock <= 0) {
+               if (__thumb_server_dcm_create_socket(&g_dcm_communicate_sock, THUMB_SERVER_DCM_PORT_DCM_SVC_APP_RECV) < 0) {
+                       thumb_err("ms_ipc_create_server_socket failed");
+                       return FALSE;
+               }
+       }
+/*     if (!__thumb_server_dcm_agent_recv_msg_from_server()) {
+               thumb_err("_thumb_server_dcm_agent_recv_msg_from_server is failed");
+               return FALSE;
+       }*/
+
+       thumb_dbg("Exec DCM_SVC: end");
+
+       return TRUE;
+}
+
+static int __thumb_server_dcm_process_recv_msg(thumb_server_dcm_ipc_msg_s *recv_msg)
+{
+       DCM_CHECK_VAL(recv_msg, MS_MEDIA_ERR_INVALID_PARAMETER);
+       int err = MS_MEDIA_ERR_NONE;
+
+       if (g_shutdowning_dcm_server) {
+               thumb_err("Thumb server is shutting down... wait for complete");
+               usleep(10000);
+               return MS_MEDIA_ERR_SOCKET_INTERNAL;
+       }
+
+       if (g_folk_dcm_server == FALSE && g_dcm_server_extracting == FALSE) {
+               if(__thumb_server_dcm_check_process() == FALSE) {  // dcm-svc is running?
+                       thumb_warn("Dcm-svc server is not running.. so start it");
+                       memcpy(&last_msg, recv_msg, sizeof(thumb_server_dcm_ipc_msg_s));
+                       if (!__thumb_server_dcm_agent_execute_server()) {
+                               thumb_err("__thumb_server_dcm_agent_execute_server is failed");
+                               return MS_MEDIA_ERR_SOCKET_INTERNAL;
+                       } else {
+                               __thumb_server_dcm_create_timer(g_dcm_timer_id);
+                               return err;
+                       }
+               }
+       } else {
+               /* Timer is re-created*/
+               __thumb_server_dcm_create_timer(g_dcm_timer_id);
+       }
+
+       if (recv_msg->msg_type == THUMB_SERVER_DCM_MSG_SCAN_ALL) {
+               /* Launch dcm-svc application to scan all images */
+               err = _thumb_server_dcm_send_msg(THUMB_SERVER_DCM_MSG_SCAN_ALL, recv_msg->uid, NULL, THUMB_SERVER_DCM_PORT_DCM_SVC_APP_RECV);
+       } else if (recv_msg->msg_type == THUMB_SERVER_DCM_MSG_SCAN_SINGLE) {
+               /* Launch dcm-svc application to scan a single image */
+               if (recv_msg->msg_size > 0) {
+                       char *file_path = strdup(recv_msg->msg);
+                       if (file_path == NULL) {
+                               thumb_err("Failed to get file path!");
+                               return MS_MEDIA_ERR_INVALID_PARAMETER;
+                       }
+
+                       thumb_warn("Send socket message to dcm-svc");
+                       err = _thumb_server_dcm_send_msg(THUMB_SERVER_DCM_MSG_SCAN_SINGLE, recv_msg->uid, (const char *)file_path, THUMB_SERVER_DCM_PORT_DCM_SVC_APP_RECV);
+                       SAFE_FREE(file_path);
+               } else {
+                       thumb_err("Invalid receive message!");
+                       err = MS_MEDIA_ERR_SOCKET_INTERNAL;
+               }
+       } else if (recv_msg->msg_type == THUMB_SERVER_DCM_MSG_SERVER_READY) {
+               thumb_warn("Recieve ready message from dcm-svc, send message to dcm-svc again");
+               err = __thumb_server_dcm_process_recv_msg(&last_msg);
+               //memset(&last_msg, 0, sizeof(thumb_server_dcm_ipc_msg_s));
+       } else if (recv_msg->msg_type == THUMB_SERVER_DCM_MSG_STOP) {
+               err = _thumb_server_dcm_send_msg(THUMB_SERVER_DCM_MSG_STOP, 0, NULL, THUMB_SERVER_DCM_PORT_DCM_SVC_APP_RECV);
+               __thumb_server_dcm_create_timer(g_dcm_timer_id);
+       } else {
+               thumb_err("Invalid message type!");
+               err = MS_MEDIA_ERR_SOCKET_INTERNAL;
+       }
+
+       if (g_dcm_communicate_sock > 0) { // THUMB_REQUEST_ALL_MEDIA
+               g_dcm_server_extracting = TRUE;
+       }
+
+       return err;
+}
+
+static int __thumb_server_dcm_receive_tcp_msg(int client_sock, thumb_server_dcm_ipc_msg_s *recv_msg)
+{
+       int recv_msg_size = 0;
+
+       if ((recv_msg_size = read(client_sock, recv_msg, sizeof(thumb_server_dcm_ipc_msg_s))) < 0) {
+               if (errno == EWOULDBLOCK) {
+                       thumb_err("Timeout. Can't try any more");
+                       return MS_MEDIA_ERR_SOCKET_RECEIVE;
+               } else {
+                       thumb_err("recv failed : %s", strerror(errno));
+                       return MS_MEDIA_ERR_SOCKET_RECEIVE;
+               }
+       }
+
+       thumb_dbg_slog("tomoryu __thumb_server_dcm_receive_tcp_msg() uid : %d, sock : %d", recv_msg->uid, client_sock);
+       thumb_dbg_slog("[receive msg] type: %d, msg: %s, msg_size: %d", recv_msg->msg_type, recv_msg->msg, recv_msg->msg_size);
+
+       if (!(recv_msg->msg_type >= 0 && recv_msg->msg_type < THUMB_SERVER_DCM_MSG_MAX)) {
+               thumb_err("IPC message is wrong!");
+               return  MS_MEDIA_ERR_SOCKET_RECEIVE;
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+static int __thumb_server_dcm_accept_tcp_socket(int serv_sock, int* client_sock)
+{
+       DCM_CHECK_VAL(client_sock, MS_MEDIA_ERR_INVALID_PARAMETER);
+       int sockfd = -1;
+       struct sockaddr_un client_addr;
+       socklen_t client_addr_len = sizeof(client_addr);
+
+       if ((sockfd = accept(serv_sock, (struct sockaddr*)&client_addr, &client_addr_len)) < 0) {
+               thumb_err("accept failed : %s", strerror(errno));
+               *client_sock  = -1;
+               return MS_MEDIA_ERR_SOCKET_ACCEPT;
+       }
+
+       *client_sock  = sockfd;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+static gboolean __thumb_server_dcm_read_dcm_recv_socket(GIOChannel *src, GIOCondition condition, gpointer data)
+{
+       int sock = -1;
+       int client_sock = -1;
+       thumb_server_dcm_ipc_msg_s recv_msg;
+       int err = 0;
+
+       /* Get socket fd from IO channel */
+       sock = g_io_channel_unix_get_fd(src);
+       if (sock < 0) {
+               thumb_err("Invalid socket fd!");
+               return TRUE;
+       }
+
+       /* Accept tcp client socket */
+       err = __thumb_server_dcm_accept_tcp_socket(sock, &client_sock);
+       if (err != MS_MEDIA_ERR_NONE) {
+               thumb_err("Failed to accept tcp socket! err: %d", err);
+               return TRUE;
+       }
+
+       /* Receive message from tcp socket */
+       err = __thumb_server_dcm_receive_tcp_msg(client_sock, &recv_msg);
+       if (err != MS_MEDIA_ERR_NONE) {
+               thumb_err("Failed to receive tcp msg! err: %d", err);
+               goto DCM_IPC_READ_TCP_SOCKET_FAILED;
+       }
+
+       /* Process received message */
+       err = __thumb_server_dcm_process_recv_msg(&recv_msg);
+       if (err != MS_MEDIA_ERR_NONE) {
+               thumb_err("Error ocurred when process received message: %d", err);
+               goto DCM_IPC_READ_TCP_SOCKET_FAILED;
+       }
+
+DCM_IPC_READ_TCP_SOCKET_FAILED:
+
+       if (close(client_sock) < 0) {
+               thumb_err("close failed [%s]", strerror(errno));
+       }
+
+       return TRUE;
+}
+
+static int __thumb_server_dcm_create_socket(int *socket_fd, thumb_server_dcm_port_type_e port)
+{
+       DCM_CHECK_VAL(socket_fd, MS_MEDIA_ERR_INVALID_PARAMETER);
+       int sock = -1;
+       struct sockaddr_un serv_addr;
+       bool bind_success = false;
+       int i = 0;
+
+       /* Create a new TCP socket */
+       if ((sock = socket(PF_FILE, SOCK_STREAM, 0)) < 0) {
+               thumb_err("socket failed: %s", strerror(errno));
+               return MS_MEDIA_ERR_SOCKET_CONN;
+       }
+
+       /* Set socket address */
+       memset(&serv_addr, 0, sizeof(serv_addr));
+       serv_addr.sun_family = AF_UNIX;
+       unlink(DCM_IPC_PATH[port]);
+       strcpy(serv_addr.sun_path, DCM_IPC_PATH[port]);
+
+       /* Bind socket to local address */
+       for (i = 0; i < 20; i ++) {
+               if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == 0) {
+                       bind_success = true;
+                       break;
+               }
+               thumb_dbg("#%d bind",i);
+               usleep(250000);
+       }
+
+       if (bind_success == false) {
+               thumb_err("bind failed : %s %d_", strerror(errno), errno);
+               close(sock);
+               return MS_MEDIA_ERR_SOCKET_BIND;
+       }
+       thumb_dbg("bind success");
+
+       /* Listenint */
+       if (listen(sock, SOMAXCONN) < 0) {
+               thumb_err("listen failed : %s", strerror(errno));
+               close(sock);
+               return MS_MEDIA_ERR_SOCKET_CONN;
+       }
+       thumb_dbg("Listening...");
+
+       /* change permission of local socket file */
+       if (chmod(DCM_IPC_PATH[port], 0660) < 0)
+               thumb_err("chmod failed [%s]", strerror(errno));
+       if (chown(DCM_IPC_PATH[port], 0, 5000) < 0)
+               thumb_err("chown failed [%s]", strerror(errno));
+
+       *socket_fd = sock;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+gboolean _thumb_server_dcm_thread(void *data)
+{
+       int socket_fd = -1;
+       GSource *source = NULL;
+       GIOChannel *channel = NULL;
+       GMainContext *context = NULL;
+       int err = 0;
+
+       thumb_err( "_thumb_server_dcm_thread!S");
+
+
+       /* Create TCP Socket to receive message from thumb server main thread */
+       err = __thumb_server_dcm_create_socket(&socket_fd, THUMB_SERVER_DCM_PORT_DCM_RECV);
+       if (err != MS_MEDIA_ERR_NONE) {
+               thumb_err("Failed to create socket! err: %d", err);
+               return FALSE;
+       }
+       thumb_warn_slog("dcm recv socket: %d", socket_fd);
+
+       /* Create a new main context for dcm thread */
+       context = g_main_context_new();
+
+       /* Create a new main event loop */
+       g_dcm_thread_mainloop = g_main_loop_new(context, FALSE);
+
+       /* Create a new channel to watch TCP socket */
+       channel = g_io_channel_unix_new(socket_fd);
+       source = g_io_create_watch(channel, G_IO_IN);
+
+       /* Attach channel to main context in dcm thread */
+       g_source_set_callback(source, (GSourceFunc)__thumb_server_dcm_read_dcm_recv_socket, NULL, NULL);
+       g_source_attach(source, context);
+
+       /* Push main context to dcm thread */
+       g_main_context_push_thread_default(context);
+
+       /* dcm-svc is launched by service_send_launch_request the first time */
+       b_dcm_svc_launched = false;
+
+       thumb_dbg("********************************************");
+       thumb_dbg("*** Thumb Server DCM thread is running   ***");
+       thumb_dbg("********************************************");
+
+       /* Start to run main event loop for dcm thread */
+       g_main_loop_run(g_dcm_thread_mainloop);
+
+       thumb_dbg("*** Thumb Server DCM thread will be closed ***");
+
+       /* Destroy IO channel */
+       g_io_channel_shutdown(channel,  FALSE, NULL);
+       g_io_channel_unref(channel);
+
+       /* Close the TCP socket */
+       close(socket_fd);
+
+       /* Descrease the reference count of main loop of dcm thread */
+       g_main_loop_unref(g_dcm_thread_mainloop);
+
+       return FALSE;
+}
+
+int _thumb_server_dcm_send_msg(thumb_server_dcm_ipc_msg_type_e msg_type, uid_t uid, const char *msg, thumb_server_dcm_port_type_e port)
+{
+       if (port < 0 || port >= THUMB_SERVER_DCM_PORT_MAX) {
+               thumb_err("Invalid port! Stop sending message...");
+               return MS_MEDIA_ERR_SOCKET_SEND;
+       }
+
+       thumb_err( "_thumb_server_dcm_send_msg to %d ", port);
+
+       int socket_fd = -1;
+       struct sockaddr_un serv_addr;
+       //struct timeval tv_timeout = { 10, 0 }; /* timeout: 10 seconds */
+       thumb_server_dcm_ipc_msg_s send_msg;
+
+       /* Prepare send message */
+       memset((void *)&send_msg, 0, sizeof(thumb_server_dcm_ipc_msg_s));
+       send_msg.uid = uid;
+       send_msg.msg_type = msg_type;
+       if (msg != NULL) {
+               send_msg.msg_size = strlen(msg);
+               strncpy(send_msg.msg, msg, send_msg.msg_size);
+       }
+
+       /* Create a new TCP socket */
+       if ((socket_fd = socket(PF_FILE, SOCK_STREAM, 0)) < 0) {
+               thumb_err("socket failed: %s", strerror(errno));
+               return MS_MEDIA_ERR_SOCKET_CONN;
+       }
+
+       /* Set dcm thread socket address */
+       memset(&serv_addr, 0, sizeof(serv_addr));
+       serv_addr.sun_family = AF_UNIX;
+       strcpy(serv_addr.sun_path, DCM_IPC_PATH[port]);
+
+       /* Connect to the socket */
+       if (connect(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
+               thumb_err("connect error : %s", strerror(errno));
+               close(socket_fd);
+               return MS_MEDIA_ERR_SOCKET_CONN;
+       }
+
+       /* Send msg to the socket */
+       if (send(socket_fd, &send_msg, sizeof(send_msg), 0) != sizeof(send_msg)) {
+               thumb_err("send failed : %s", strerror(errno));
+               close(socket_fd);
+               return MS_MEDIA_ERR_SOCKET_SEND;
+       }
+
+       if (msg_type >= THUMB_SERVER_DCM_MSG_STOP && g_dcm_communicate_sock > 0) { // THUMB_REQUEST_ALL_MEDIA
+               g_dcm_server_extracting = TRUE;
+       }
+
+       close(socket_fd);
+       return MS_MEDIA_ERR_NONE;
+}
+
+void _thumb_server_dcm_quit_main_loop()
+{
+       if (g_dcm_thread_mainloop != NULL) {
+               thumb_warn("Quit DCM thread main loop!");
+               g_main_loop_quit(g_dcm_thread_mainloop);
+       } else {
+               thumb_err("Invalid DCM thread main loop!");
+       }
+}
+
+int thumb_server_dcm_get_server_pid()
+{
+       return g_dcm_server_pid;
+}
+
+void thumb_server_dcm_reset_server_status()
+{
+       g_folk_dcm_server = FALSE;
+       g_shutdowning_dcm_server = FALSE;
+
+       if (g_dcm_timer_id > 0) {
+               g_source_destroy(g_main_context_find_source_by_id(g_main_context_get_thread_default(), g_dcm_timer_id));
+               g_dcm_timer_id = 0;
+       }
+
+       if (g_dcm_server_extracting) {
+               /* Need to inplement when crash happens */
+               thumb_err("Thumbnail server is dead when processing all-thumbs extraction");
+               g_dcm_server_extracting = FALSE;
+               g_dcm_server_pid = 0;
+       } else {
+               g_dcm_server_extracting = FALSE;
+               g_dcm_server_pid = 0;
+       }
+
+       return;
+}
+#endif /* _SUPPORT_DCM */
index 5facdee..e9e9530 100755 (executable)
 #undef LOG_TAG
 #endif
 
+#ifdef _SUPPORT_DCM
+#include "thumb-server-dcm.h"
+#endif /* _SUPPORT_DCM */
+
 #define LOG_TAG "MEDIA_THUMBNAIL_SERVER"
 #define THUMB_DEFAULT_WIDTH 320
 #define THUMB_DEFAULT_HEIGHT 240
@@ -391,12 +395,22 @@ gboolean _thumb_server_read_socket(GIOChannel *src,
                thumb_dbg("All thumbnails are being extracted now");
                __thumb_daemon_all_extract(recv_msg.uid);
                g_idle_add(_thumb_daemon_process_queue_jobs, NULL);
+               
+#ifdef _SUPPORT_DCM
+               /* Send msg to dcm thread to scan all images */
+               _thumb_server_dcm_send_msg(THUMB_SERVER_DCM_MSG_SCAN_ALL, recv_msg.uid, NULL, THUMB_SERVER_DCM_PORT_DCM_RECV);
+#endif /* _SUPPORT_DCM */
        } else if(recv_msg.msg_type == THUMB_REQUEST_RAW_DATA) {
                __thumb_daemon_process_job_raw(&recv_msg, &res_msg);
        } else if(recv_msg.msg_type == THUMB_REQUEST_KILL_SERVER) {
                thumb_warn("received KILL msg from thumbnail agent.");
        } else {
                _thumb_daemon_process_job(&recv_msg, &res_msg,recv_msg.uid);
+
+#ifdef _SUPPORT_DCM
+               /* Send msg to dcm thread to scan a single image */
+               _thumb_server_dcm_send_msg(THUMB_SERVER_DCM_MSG_SCAN_SINGLE, recv_msg.uid, (const char *)(recv_msg.org_path), THUMB_SERVER_DCM_PORT_DCM_RECV);
+#endif /* _SUPPORT_DCM */
        }
 
        if(res_msg.msg_type == 0)
@@ -438,6 +452,10 @@ gboolean _thumb_server_read_socket(GIOChannel *src,
 
        if(recv_msg.msg_type == THUMB_REQUEST_KILL_SERVER) {
                thumb_warn("Shutting down...");
+#ifdef _SUPPORT_DCM
+               /* Quit dcm thread main loop */
+               _thumb_server_dcm_quit_main_loop();
+#endif
                g_main_loop_quit(g_thumb_server_mainloop);
        }
 
index 8e191f5..44bd2eb 100755 (executable)
 #include <pthread.h>
 #include <vconf.h>
 
+#ifdef _SUPPORT_DCM
+#include "thumb-server-dcm.h"
+#endif /* _SUPPORT_DCM */
+
 #ifdef LOG_TAG
 #undef LOG_TAG
 #endif
@@ -49,6 +53,44 @@ static void _media_thumb_signal_handler(void *user_data)
 }
 #endif
 
+#ifdef _SUPPORT_DCM
+void _thumb_server_signal_handler(int n)
+{
+       int stat, pid, dcm_pid;
+
+       dcm_pid = thumb_server_dcm_get_server_pid();
+
+       while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) {
+               /* check pid of child process of thumbnail thread */
+               if (pid == dcm_pid) {
+                       thumb_err("[%d] Dcm-svc server is stopped by media-thumb-server", pid);
+                       thumb_server_dcm_reset_server_status();
+               } else {
+                       thumb_err("[%d] is stopped", pid);
+               }
+       }
+
+       return;
+}
+
+static void _thumb_server_add_signal_handler(void)
+{
+       struct sigaction sigset;
+
+       /* Add signal handler */
+       sigemptyset(&sigset.sa_mask);
+       sigaddset(&sigset.sa_mask, SIGCHLD);
+       sigset.sa_flags = SA_RESTART |SA_NODEFER;
+       sigset.sa_handler = _thumb_server_signal_handler;
+
+       if (sigaction(SIGCHLD, &sigset, NULL) < 0) {
+               thumb_err("sigaction failed [%s]", strerror(errno));
+       }
+
+       signal(SIGPIPE,SIG_IGN);
+}
+#endif
+
 int main(void)
 {
        int sockfd = -1;
@@ -79,6 +121,10 @@ int main(void)
                return -1;
        }
 
+#ifdef _SUPPORT_DCM
+       _thumb_server_add_signal_handler();
+#endif
+
        g_thumb_server_mainloop = g_main_loop_new(context, FALSE);
        context = g_main_loop_get_context(g_thumb_server_mainloop);
 
@@ -95,6 +141,13 @@ int main(void)
        g_source_set_callback (source_evas_init, _thumb_daemon_start_jobs, NULL, NULL);
        g_source_attach (source_evas_init, context);
 
+#ifdef _SUPPORT_DCM
+       thumb_dbg( "[GD] _thumb_server_dcm_thread created");
+       /* Create dcm thread */
+       GThread *dcm_thread = NULL;
+       dcm_thread = g_thread_new("dcm_thread", (GThreadFunc)_thumb_server_dcm_thread, NULL);
+#endif /* _SUPPORT_DCM */
+
 /*     Would be used when glib 2.32 is installed
        GSource *sig_handler_src = NULL;
        sig_handler_src = g_unix_signal_source_new (SIGTERM);
@@ -111,6 +164,11 @@ int main(void)
        g_io_channel_shutdown(channel,  FALSE, NULL);
        g_io_channel_unref(channel);
        _thumb_daemon_finish_jobs();
+
+#ifdef _SUPPORT_DCM
+       /* Finish dcm thread */
+       g_thread_join(dcm_thread);
+#endif /* _SUPPORT_DCM */
        g_main_loop_unref(g_thumb_server_mainloop);
        ms_cynara_finish();