+++ /dev/null
-/*
- * media-thumbnail-server
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hyunjun Ko <zzoon.ko@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 "media-util.h"
-#include "media-common-utils.h"
-#include "media-server-dbg.h"
-#include "media-server-thumb.h"
-#include <tzplatform_config.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-
-#define LOG_TAG "MEDIA_SERVER_THUMB"
-
-#define THUMB_SERVER_PATH tzplatform_mkpath(TZ_SYS_BIN, "media-thumbnail-server")
-
-static GMainLoop *g_thumb_agent_loop = NULL;
-static gboolean g_thumb_server_forked = FALSE;
-static gboolean g_shutdowning_thumb_server = FALSE;
-static int g_communicate_sock = -1;
-static int g_timer_id = 0;
-static int g_server_pid = 0;
-
-static GQueue *g_request_queue = NULL;
-static gboolean g_queue_work = FALSE;
-static guint g_thumb_agent_source_id;
-
-typedef struct {
- int client_sock;
- thumbMsg *recv_msg;
-} thumbRequest;
-
-extern char MEDIA_IPC_PATH[][70];
-
-void ms_thumb_finalize(void)
-{
- if (g_communicate_sock != -1) {
- close(g_communicate_sock);
- g_communicate_sock = -1;
- }
-
- if (g_main_loop_is_running(g_thumb_agent_loop)) {
- g_source_destroy(g_main_context_find_source_by_id(g_main_context_get_thread_default(), g_thumb_agent_source_id));
- g_main_loop_quit(g_thumb_agent_loop);
- }
-}
-
-int ms_thumb_get_server_pid(void)
-{
- return g_server_pid;
-}
-
-void ms_thumb_reset_server_status(void)
-{
- g_thumb_server_forked = FALSE;
- g_shutdowning_thumb_server = FALSE;
-
- if (g_timer_id > 0) {
- g_source_destroy(g_main_context_find_source_by_id(g_main_context_get_thread_default(), g_timer_id));
- g_timer_id = 0;
- }
-
- g_server_pid = 0;
-}
-
-static gboolean __ms_thumb_agent_prepare_tcp_socket(int *sock_fd, unsigned short serv_port)
-{
- if (ms_ipc_create_server_socket(serv_port, sock_fd) < 0) {
- MS_DBG_ERR("_ms_thumb_create_socket failed");
- return FALSE;
- }
-
- return TRUE;
-}
-
-static int __ms_thumb_recv_msg(int sock, thumbMsg *msg)
-{
- if (!msg)
- return MS_MEDIA_ERR_INVALID_PARAMETER;
-
- if (recv(sock, msg, sizeof(thumbMsg), 0) < 0) {
- MS_DBG_STRERROR("recv failed");
- return MS_MEDIA_ERR_IPC;
- }
-
- MS_DBG("status[%d]", msg->status);
- MS_DBG_RETVM_IF(msg->msg_type == THUMB_REQUEST_KILL_SERVER, MS_MEDIA_ERR_IPC, "Wrong msg");
- MS_DBG_RETVM_IF(strlen(msg->org_path) == 0 || strlen(msg->org_path) >= MS_FILE_PATH_LEN_MAX, MS_MEDIA_ERR_IPC, "Invalid org_path");
- MS_DBG_RETVM_IF(strlen(msg->dst_path) >= MS_FILE_PATH_LEN_MAX, MS_MEDIA_ERR_IPC, "Invalid dst_path");
-
- return MS_MEDIA_ERR_NONE;
-}
-
-static gboolean __ms_thumb_agent_recv_msg_from_server(void)
-{
- struct sockaddr_un serv_addr;
- unsigned int serv_addr_len;
- ms_thumb_server_msg recv_msg;
- int len = 0;
- int sockfd = -1;
-
- if (g_communicate_sock <= 0)
- __ms_thumb_agent_prepare_tcp_socket(&g_communicate_sock, MS_THUMB_COMM_PORT);
-
- serv_addr_len = sizeof(serv_addr);
-
- if ((sockfd = accept(g_communicate_sock, (struct sockaddr*)&serv_addr, &serv_addr_len)) < 0) {
- MS_DBG_STRERROR("accept failed");
- return FALSE;
- }
-
- if ((len = read(sockfd, &recv_msg, sizeof(ms_thumb_server_msg))) < 0) {
- MS_DBG_STRERROR("read failed");
- close(sockfd);
- return FALSE;
- }
-
- if (recv_msg.msg_type == MS_MSG_THUMB_SERVER_READY)
- MS_DBG("Thumbnail server is ready");
-
- close(sockfd);
- return TRUE;
-}
-
-static gboolean __ms_thumb_agent_execute_server(void)
-{
- int pid;
- pid = fork();
-
- if (pid < 0) {
- return FALSE;
- } else if (pid == 0) {
- execl(THUMB_SERVER_PATH, "media-thumbnail-server", NULL);
- } else {
- MS_DBG("Child process is %d", pid);
- g_thumb_server_forked = TRUE;
- }
-
- g_server_pid = pid;
-
- if (!__ms_thumb_agent_recv_msg_from_server()) {
- MS_DBG_ERR("_ms_thumb_agent_recv_msg_from_server is failed");
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean __ms_thumb_agent_send_msg_to_thumb_server(thumbMsg *recv_msg, thumbMsg *res_msg)
-{
- int sock;
- struct sockaddr_un serv_addr;
-
- MS_DBG_RETVM_IF(!recv_msg || strlen(recv_msg->org_path) >= MAX_FILEPATH_LEN, FALSE, "Invalid msg");
-
- if (ms_ipc_create_client_socket(MS_TIMEOUT_SEC_10, &sock) < 0) {
- MS_DBG_ERR("ms_ipc_create_client_socket failed");
- return FALSE;
- }
-
- memset(&serv_addr, 0, sizeof(serv_addr));
- serv_addr.sun_family = AF_UNIX;
- SAFE_STRLCPY(serv_addr.sun_path, tzplatform_mkpath(TZ_SYS_RUN, MEDIA_IPC_PATH[MS_THUMB_DAEMON_PORT]), sizeof(serv_addr.sun_path));
-
- /* Connecting to the thumbnail server */
- if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
- MS_DBG_STRERROR("connect failed");
- close(sock);
- return FALSE;
- }
-
- if (send(sock, recv_msg, sizeof(thumbMsg), 0) < 0) {
- MS_DBG_STRERROR("send failed");
- close(sock);
- return FALSE;
- }
-
- MS_DBG_SLOG("Sending msg to thumbnail server is successful");
-
- if (recv_msg->msg_type == THUMB_REQUEST_KILL_SERVER) {
- MS_DBG_SLOG("No response if msg type is kill server[%d]", recv_msg->msg_type);
- close(sock);
- return TRUE;
- }
-
- if (__ms_thumb_recv_msg(sock, res_msg) < 0) {
- MS_DBG_ERR("_ms_thumb_recv_msg failed");
- close(sock);
- return FALSE;
- }
-
- if (res_msg->status == MS_MEDIA_ERR_NONE)
- MS_DBG_SLOG("recv %s from thumb daemon is successful", res_msg->dst_path);
- else
- MS_DBG_SLOG("recv %s from thumb daemon is failed (%d)", res_msg->dst_path, res_msg->status);
-
- close(sock);
-
- return TRUE;
-}
-
-static gboolean __ms_thumb_agent_timer(gpointer data)
-{
- g_timer_id = 0;
- MS_DBG("Timer is called.. Now killing media-thumbnail-server[%d]", g_server_pid);
-
- if (g_server_pid > 0) {
- /* Kill thumbnail server */
- thumbMsg msg;
- memset((void *)&msg, 0, sizeof(msg));
-
- msg.msg_type = THUMB_REQUEST_KILL_SERVER;
- msg.org_path[0] = '\0';
- msg.dst_path[0] = '\0';
-
- /* Command Kill to thumbnail server */
- g_shutdowning_thumb_server = TRUE;
- if (!__ms_thumb_agent_send_msg_to_thumb_server(&msg, NULL)) {
- MS_DBG_ERR("_ms_thumb_agent_send_msg_to_thumb_server is failed");
- g_shutdowning_thumb_server = FALSE;
- }
- usleep(200000);
- } else {
- MS_DBG_ERR("g_server_pid is %d. Maybe there's problem in thumbnail-server", g_server_pid);
- }
-
- return G_SOURCE_REMOVE;
-}
-
-static void __ms_thumb_create_timer(void)
-{
- if (g_timer_id > 0)
- g_source_destroy(g_main_context_find_source_by_id(g_main_context_get_thread_default(), g_timer_id));
-
- GSource *timer_src = g_timeout_source_new_seconds(MS_TIMEOUT_SEC_20);
- g_source_set_callback(timer_src, __ms_thumb_agent_timer, NULL, NULL);
- g_timer_id = g_source_attach(timer_src, g_main_context_get_thread_default());
- g_source_unref(timer_src);
-}
-
-static gboolean __ms_thumb_request_to_server(gpointer data)
-{
- thumbRequest *req = NULL;
- guint req_len = g_queue_get_length(g_request_queue);
-
- MS_DBG("Queue length : %d", req_len);
- if (req_len == 0) {
- g_queue_work = FALSE;
- return G_SOURCE_REMOVE;
- }
-
- if (g_shutdowning_thumb_server) {
- MS_DBG_WARN("Thumb server is shutting down... wait for complete");
- usleep(10000);
- return G_SOURCE_CONTINUE;
- }
-
- if (!g_thumb_server_forked) {
- MS_DBG_WARN("Thumb server is not running.. so start it");
- if (!__ms_thumb_agent_execute_server()) {
- MS_DBG_ERR("_ms_thumb_agent_execute_server is failed");
- g_queue_work = FALSE;
- return G_SOURCE_REMOVE;
- }
- }
- __ms_thumb_create_timer();
-
- req = (thumbRequest *)g_queue_pop_head(g_request_queue);
- MS_DBG_RETVM_IF(!req, TRUE, "Failed to get a request job from queue");
-
- int client_sock = -1;
- thumbMsg *recv_msg = NULL;
- thumbMsg res_msg;
- memset((void *)&res_msg, 0, sizeof(res_msg));
-
- client_sock = req->client_sock;
- recv_msg = req->recv_msg;
-
- if (client_sock <= 0 || !recv_msg) {
- MS_DBG_ERR("client sock is below 0 or recv msg is NULL");
- g_free(req->recv_msg);
- g_free(req);
- return G_SOURCE_CONTINUE;
- }
-
- if (!__ms_thumb_agent_send_msg_to_thumb_server(recv_msg, &res_msg)) {
- MS_DBG_ERR("_ms_thumb_agent_send_msg_to_thumb_server is failed");
-
- thumbMsg res_msg;
- memset((void *)&res_msg, 0, sizeof(res_msg));
-
- res_msg.msg_type = THUMB_RESPONSE;
- res_msg.status = MS_MEDIA_ERR_INTERNAL;
- SAFE_STRLCPY(res_msg.org_path, recv_msg->org_path, sizeof(res_msg.org_path));
- res_msg.dst_path[0] = '\0';
-
- if (send(client_sock, &res_msg, sizeof(thumbMsg), 0) < 0)
- MS_DBG_STRERROR("send failed");
- else
- MS_DBG("Sent Refuse msg from %s", recv_msg->org_path);
-
- close(client_sock);
-
- g_free(req->recv_msg);
- g_free(req);
-
- return G_SOURCE_CONTINUE;
- }
-
- SAFE_STRLCPY(res_msg.org_path, recv_msg->org_path, sizeof(res_msg.org_path));
-
- if (send(client_sock, &res_msg, sizeof(thumbMsg), 0) < 0)
- MS_DBG_STRERROR("send failed");
-
- close(client_sock);
- g_free(req->recv_msg);
- g_free(req);
-
- return G_SOURCE_CONTINUE;
-}
-
-static gboolean __ms_thumb_agent_read_socket(GIOChannel *src, GIOCondition condition, gpointer data)
-{
- struct sockaddr_un client_addr;
- unsigned int client_addr_len;
- thumbMsg *recv_msg = NULL;
- int sock = -1;
- int client_sock = -1;
- thumbRequest *thumb_req = NULL;
-
- sock = g_io_channel_unix_get_fd(src);
- MS_DBG_RETVM_IF(sock < 0, G_SOURCE_CONTINUE, "sock fd is invalid!");
-
- client_addr_len = sizeof(client_addr);
-
- if ((client_sock = accept(sock, (struct sockaddr*)&client_addr, &client_addr_len)) < 0) {
- MS_DBG_STRERROR("accept failed");
- return G_SOURCE_CONTINUE;
- }
-
- MS_DBG("Client[%d] is accepted", client_sock);
-
- recv_msg = g_new0(thumbMsg, 1);
-
- if (__ms_thumb_recv_msg(client_sock, recv_msg) < 0) {
- MS_DBG_ERR("_ms_thumb_recv_msg failed ");
- goto ERROR;
- }
-
- thumb_req = g_new0(thumbRequest, 1);
-
- thumb_req->client_sock = client_sock;
- thumb_req->recv_msg = recv_msg;
-
- if (!g_request_queue) {
- MS_DBG_WARN("Creating queue");
- g_request_queue = g_queue_new();
- }
-
- if (g_queue_get_length(g_request_queue) >= MAX_THUMB_REQUEST) {
- MS_DBG_WARN("Request Queue is full");
- thumbMsg res_msg;
- memset((void *)&res_msg, 0, sizeof(res_msg));
-
- res_msg.msg_type = THUMB_RESPONSE;
- res_msg.status = MS_MEDIA_ERR_INTERNAL;
- SAFE_STRLCPY(res_msg.org_path, recv_msg->org_path, sizeof(res_msg.org_path));
- res_msg.dst_path[0] = '\0';
-
- if (send(client_sock, &res_msg, sizeof(thumbMsg), 0) < 0)
- MS_DBG_STRERROR("send failed");
- else
- MS_DBG("Sent Refuse msg from %s", recv_msg->org_path);
-
- goto ERROR;
- }
-
- MS_DBG_SLOG("%s is queued", recv_msg->org_path);
- g_queue_push_tail(g_request_queue, (gpointer)thumb_req);
-
- if (!g_queue_work) {
- GSource *src_request = NULL;
- src_request = g_idle_source_new();
- g_source_set_callback(src_request, __ms_thumb_request_to_server, NULL, NULL);
- g_source_attach(src_request, g_main_context_get_thread_default());
- g_queue_work = TRUE;
- }
-
- return G_SOURCE_CONTINUE;
-ERROR:
- close(client_sock);
- g_free(recv_msg);
- g_free(thumb_req);
- return G_SOURCE_CONTINUE;
-}
-
-
-gpointer ms_thumb_agent_start_thread(gpointer data)
-{
- int sockfd = -1;
- GSource *source = NULL;
- GIOChannel *channel = NULL;
- GMainContext *context = NULL;
-
- /* Create and bind new TCP socket */
- if (!__ms_thumb_agent_prepare_tcp_socket(&sockfd, MS_THUMB_CREATOR_PORT)) {
- MS_DBG_ERR("Failed to create socket");
- return NULL;
- }
-
- context = g_main_context_new();
-
- g_thumb_agent_loop = g_main_loop_new(context, FALSE);
- g_main_context_push_thread_default(context);
-
- /* Create new channel to watch udp socket */
- channel = g_io_channel_unix_new(sockfd);
- source = g_io_create_watch(channel, G_IO_IN);
- g_io_channel_unref(channel);
-
- /* Set callback to be called when socket is readable */
- g_source_set_callback(source, (GSourceFunc)__ms_thumb_agent_read_socket, NULL, NULL);
- g_thumb_agent_source_id = g_source_attach(source, context);
- g_source_unref(source);
-
- MS_DBG_INFO("Thumbnail Agent thread is running");
- g_main_loop_run(g_thumb_agent_loop);
- MS_DBG_INFO("Thumbnail Agent thread is shutting down");
-
- /*close an IO channel*/
- close(sockfd);
- g_main_loop_unref(g_thumb_agent_loop);
-
- return NULL;
-}