4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hyunjun Ko <zzoon.ko@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 #include "media-thumbnail.h"
23 #include "media-thumb-ipc.h"
24 #include "media-thumb-util.h"
25 #include "media-thumb-db.h"
26 #include "media-thumb-debug.h"
34 #define THUMB_SOCK_BLOCK_SIZE 512
36 static GQueue *g_request_queue = NULL;
37 static GQueue *g_manage_queue = NULL;
38 static GQueue *g_request_raw_queue = NULL;
39 static GQueue *g_manage_raw_queue = NULL;
49 thumbUserData *userData;
62 thumbRawUserData *userData;
65 int _media_thumb_send_request();
66 int _media_thumb_raw_data_send_request();
69 int _media_thumb_get_error()
71 if (errno == EWOULDBLOCK) {
72 thumb_err("Timeout. Can't try any more");
73 return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT;
75 thumb_stderror("recvfrom failed");
76 return MS_MEDIA_ERR_SOCKET_RECEIVE;
80 int __media_thumb_pop_req_queue(const char *path, bool shutdown_channel)
84 req_len = g_queue_get_length(g_request_queue);
87 // thumb_dbg("There is no request in the queue");
90 for (i = 0; i < req_len; i++) {
92 req = (thumbReq *)g_queue_peek_nth(g_request_queue, i);
93 if (req == NULL) continue;
95 if (strncmp(path, req->path, strlen(path)) == 0) {
96 if (shutdown_channel) {
97 GSource *source_id = g_main_context_find_source_by_id(g_main_context_get_thread_default(), req->source_id);
98 if (source_id != NULL) {
99 g_source_destroy(source_id);
101 thumb_err("G_SOURCE_ID is NULL");
104 g_io_channel_shutdown(req->channel, TRUE, NULL);
105 g_io_channel_unref(req->channel);
107 g_queue_pop_nth(g_request_queue, i);
109 SAFE_FREE(req->path);
110 SAFE_FREE(req->userData);
117 // thumb_dbg("There's no %s in the queue", path);
121 return MS_MEDIA_ERR_NONE;
124 int __media_thumb_check_req_queue_for_cancel(const char *path)
128 req_len = g_queue_get_length(g_request_queue);
131 // thumb_dbg("There is no request in the queue");
133 thumbReq *req = NULL;
134 req = (thumbReq *)g_queue_peek_head(g_request_queue);
136 if (req != NULL && strncmp(path, req->path, strlen(path)) == 0) {
137 req->isCanceled = true;
138 return MS_MEDIA_ERR_NONE;
142 return MS_MEDIA_ERR_INTERNAL;
145 int __media_thumb_pop_manage_queue(const char *path)
150 req_len = g_queue_get_length(g_manage_queue);
153 // thumb_dbg("There is no request in the queue");
155 for (i = 0; i < req_len; i++) {
156 thumbReq *req = NULL;
157 req = (thumbReq *)g_queue_peek_nth(g_manage_queue, i);
158 if (req == NULL) continue;
160 if (strncmp(path, req->path, strlen(path)) == 0) {
161 g_queue_pop_nth(g_manage_queue, i);
163 SAFE_FREE(req->path);
164 SAFE_FREE(req->userData);
171 return __media_thumb_check_req_queue_for_cancel(path);
175 return MS_MEDIA_ERR_NONE;
179 int __media_thumb_pop_raw_data_req_queue(int request_id, bool shutdown_channel)
183 req_len = g_queue_get_length(g_request_raw_queue);
186 // thumb_dbg("There is no request in the queue");
189 for (i = 0; i < req_len; i++) {
190 thumbRawReq *req = NULL;
191 req = (thumbRawReq *)g_queue_peek_nth(g_request_raw_queue, i);
192 if (req == NULL) continue;
194 if (request_id == req->request_id) {
195 if (shutdown_channel) {
196 GSource *source_id = g_main_context_find_source_by_id(g_main_context_get_thread_default(), req->source_id);
197 if (source_id != NULL) {
198 g_source_destroy(source_id);
200 thumb_err("G_SOURCE_ID is NULL");
203 g_io_channel_shutdown(req->channel, TRUE, NULL);
204 g_io_channel_unref(req->channel);
206 g_queue_pop_nth(g_request_raw_queue, i);
208 SAFE_FREE(req->userData);
215 // thumb_dbg("There's no %s in the queue", path);
219 return MS_MEDIA_ERR_NONE;
222 int __media_thumb_check_raw_data_req_queue_for_cancel(int request_id)
226 req_len = g_queue_get_length(g_request_raw_queue);
229 // thumb_dbg("There is no request in the queue");
231 thumbRawReq *req = NULL;
232 req = (thumbRawReq *)g_queue_peek_head(g_request_raw_queue);
234 if (req != NULL && request_id == req->request_id) {
235 req->isCanceled = true;
236 return MS_MEDIA_ERR_NONE;
240 return MS_MEDIA_ERR_INTERNAL;
243 int __media_thumb_pop_raw_data_manage_queue(int request_id)
248 req_len = g_queue_get_length(g_manage_raw_queue);
251 // thumb_dbg("There is no request in the queue");
254 for (i = 0; i < req_len; i++) {
255 thumbRawReq *req = NULL;
256 req = (thumbRawReq *)g_queue_peek_nth(g_manage_raw_queue, i);
257 if (req == NULL) continue;
259 if (request_id == req->request_id) {
260 g_queue_pop_nth(g_manage_raw_queue, i);
262 SAFE_FREE(req->userData);
269 return __media_thumb_check_raw_data_req_queue_for_cancel(request_id);
273 return MS_MEDIA_ERR_NONE;
276 int __media_thumb_check_req_queue(const char *path)
280 req_len = g_queue_get_length(g_request_queue);
282 // thumb_dbg("Queue length : %d", req_len);
283 // thumb_dbg("Queue path : %s", path);
286 // thumb_dbg("There is no request in the queue");
289 for (i = 0; i < req_len; i++) {
290 thumbReq *req = NULL;
291 req = (thumbReq *)g_queue_peek_nth(g_request_queue, i);
292 if (req == NULL) continue;
294 if (strncmp(path, req->path, strlen(path)) == 0) {
295 //thumb_dbg("Same Request - %s", path);
296 return MS_MEDIA_ERR_INVALID_PARAMETER;
303 return MS_MEDIA_ERR_NONE;
306 bool __media_thumb_check_cancel(void)
308 thumbReq *req = NULL;
309 req = (thumbReq *)g_queue_peek_head(g_request_queue);
321 bool __media_thumb_check_cancel_for_raw(void)
323 thumbRawReq *req = NULL;
324 req = (thumbRawReq *)g_queue_peek_head(g_request_raw_queue);
337 _media_thumb_recv_msg(int sock, int header_size, thumbMsg *msg)
339 int recv_msg_len = 0;
341 int block_size = THUMB_SOCK_BLOCK_SIZE;
343 unsigned char *buf = NULL;
344 unsigned char *block_buf = NULL;
346 THUMB_MALLOC(buf, header_size);
347 THUMB_MALLOC(block_buf, THUMB_SOCK_BLOCK_SIZE);
348 if (buf == NULL || block_buf == NULL) {
349 thumb_err("memory allocation failed");
351 SAFE_FREE(block_buf);
352 return MS_MEDIA_ERR_OUT_OF_MEMORY;
355 if ((recv_msg_len = recv(sock, buf, header_size, 0)) <= 0) {
356 thumb_stderror("recv failed");
358 SAFE_FREE(block_buf);
359 return _media_thumb_get_error();
362 memcpy(msg, buf, header_size);
363 //thumb_dbg("origin_path_size : %d, dest_path_size : %d, thumb_size : %d", msg->origin_path_size, msg->dest_path_size, msg->thumb_size);
366 if(msg->origin_path_size < 0 ||msg->dest_path_size < 0 || msg->thumb_size < 0) {
367 thumb_err("recv data is wrong");
368 SAFE_FREE(block_buf);
369 return MS_MEDIA_ERR_SOCKET_RECEIVE;
372 remain_size = msg->origin_path_size + msg->dest_path_size + msg->thumb_size;
373 THUMB_MALLOC(buf, remain_size);
375 SAFE_FREE(block_buf);
376 return MS_MEDIA_ERR_OUT_OF_MEMORY;
379 while(remain_size > 0) {
380 if(remain_size < THUMB_SOCK_BLOCK_SIZE) {
381 block_size = remain_size;
383 if ((recv_msg_len = recv(sock, block_buf, block_size, 0)) < 0) {
384 thumb_stderror("recv failed");
386 SAFE_FREE(block_buf);
387 return _media_thumb_get_error();
389 memcpy(buf+recv_block, block_buf, block_size);
390 recv_block += block_size;
391 remain_size -= block_size;
394 strncpy(msg->org_path, (char *)buf, msg->origin_path_size);
395 strncpy(msg->dst_path, (char *)buf + msg->origin_path_size, msg->dest_path_size);
397 SAFE_FREE(msg->thumb_data);
398 if(msg->thumb_size > 0) {
399 THUMB_MALLOC(msg->thumb_data, msg->thumb_size);
400 if(msg->thumb_data != NULL) {
401 memcpy(msg->thumb_data, buf + msg->origin_path_size + msg->dest_path_size, msg->thumb_size);
404 SAFE_FREE(block_buf);
406 return MS_MEDIA_ERR_OUT_OF_MEMORY;
411 SAFE_FREE(block_buf);
413 return MS_MEDIA_ERR_NONE;
417 _media_thumb_recv_udp_msg(int sock, int header_size, thumbMsg *msg, struct sockaddr_un *from_addr, unsigned int *from_size)
419 int recv_msg_len = 0;
420 unsigned int from_addr_size = sizeof(struct sockaddr_un);
421 unsigned char *buf = NULL;
423 THUMB_MALLOC(buf, sizeof(thumbMsg));
425 thumb_err("memory allocation failed");
426 return MS_MEDIA_ERR_OUT_OF_MEMORY;
429 if ((recv_msg_len = recvfrom(sock, buf, sizeof(thumbMsg), 0, (struct sockaddr *)from_addr, &from_addr_size)) < 0) {
430 thumb_stderror("recvform failed");
432 return _media_thumb_get_error();
435 memcpy(msg, buf, header_size);
437 if (msg->origin_path_size <= 0 || msg->origin_path_size > MAX_PATH_SIZE) {
439 thumb_err("msg->origin_path_size is invalid %d", msg->origin_path_size );
440 return MS_MEDIA_ERR_INVALID_PARAMETER;
443 strncpy(msg->org_path, (char*)buf + header_size, msg->origin_path_size);
445 if (msg->dest_path_size <= 0 || msg->dest_path_size > MAX_PATH_SIZE) {
447 thumb_err("msg->origin_path_size is invalid %d", msg->dest_path_size );
448 return MS_MEDIA_ERR_INVALID_PARAMETER;
451 strncpy(msg->dst_path, (char*)buf + header_size + msg->origin_path_size, msg->dest_path_size);
454 *from_size = from_addr_size;
456 return MS_MEDIA_ERR_NONE;
460 _media_thumb_set_buffer(thumbMsg *req_msg, unsigned char **buf, int *buf_size)
462 if (req_msg == NULL || buf == NULL) {
463 return MS_MEDIA_ERR_INVALID_PARAMETER;
466 int org_path_len = 0;
467 int dst_path_len = 0;
468 int thumb_data_len = 0;
472 header_size = sizeof(thumbMsg) -(MAX_FILEPATH_LEN * 2) - sizeof(unsigned char *);
473 org_path_len = req_msg->origin_path_size;
474 dst_path_len = req_msg->dest_path_size;
475 thumb_data_len = req_msg->thumb_size;
477 //thumb_dbg("Basic Size : %d, org_path : %s[%d], dst_path : %s[%d], thumb_data_len : %d", header_size, req_msg->org_path, org_path_len, req_msg->dst_path, dst_path_len, thumb_data_len);
479 size = header_size + org_path_len + dst_path_len + thumb_data_len;
480 THUMB_MALLOC(*buf, size);
485 memcpy(*buf, req_msg, header_size);
486 memcpy((*buf)+header_size, req_msg->org_path, org_path_len);
487 memcpy((*buf)+header_size + org_path_len, req_msg->dst_path, dst_path_len);
488 if(thumb_data_len > 0)
489 memcpy((*buf)+header_size + org_path_len + dst_path_len, req_msg->thumb_data, thumb_data_len);
493 return MS_MEDIA_ERR_NONE;
497 _media_thumb_request(int msg_type, const char *origin_path, char *thumb_path, int max_length, media_thumb_info *thumb_info, uid_t uid)
500 struct sockaddr_un serv_addr;
501 ms_sock_info_s sock_info;
502 int recv_str_len = 0;
503 int err = MS_MEDIA_ERR_NONE;
505 sock_info.port = MS_THUMB_CREATOR_PORT;
507 err = ms_ipc_create_client_socket(MS_PROTOCOL_TCP, MS_TIMEOUT_SEC_10, &sock_info);
508 if (err != MS_MEDIA_ERR_NONE) {
509 thumb_err("ms_ipc_create_client_socket failed");
513 memset(&serv_addr, 0, sizeof(serv_addr));
514 sock = sock_info.sock_fd;
515 serv_addr.sun_family = AF_UNIX;
516 strcpy(serv_addr.sun_path, "/var/run/media-server/media_ipc_thumbcreator.socket");
518 /* Connecting to the thumbnail server */
519 if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
520 thumb_stderror("connect");
521 ms_ipc_delete_client_socket(&sock_info);
522 return MS_MEDIA_ERR_SOCKET_CONN;
528 memset((void *)&req_msg, 0, sizeof(thumbMsg));
529 memset((void *)&recv_msg, 0, sizeof(thumbMsg));
531 /* Get PID of client*/
535 /* Set requset message */
536 req_msg.msg_type = msg_type;
538 strncpy(req_msg.org_path, origin_path, sizeof(req_msg.org_path));
539 req_msg.org_path[strlen(req_msg.org_path)] = '\0';
541 if (msg_type == THUMB_REQUEST_SAVE_FILE) {
542 strncpy(req_msg.dst_path, thumb_path, sizeof(req_msg.dst_path));
543 req_msg.dst_path[strlen(req_msg.dst_path)] = '\0';
546 req_msg.origin_path_size = strlen(req_msg.org_path) + 1;
547 req_msg.dest_path_size = strlen(req_msg.dst_path) + 1;
548 req_msg.thumb_size = 0;
550 if (req_msg.origin_path_size > MAX_PATH_SIZE || req_msg.dest_path_size > MAX_PATH_SIZE) {
551 thumb_err("path's length exceeds %d", MAX_PATH_SIZE);
552 ms_ipc_delete_client_socket(&sock_info);
553 return MS_MEDIA_ERR_INVALID_PARAMETER;
556 unsigned char *buf = NULL;
560 header_size = sizeof(thumbMsg) - MAX_PATH_SIZE*2 - sizeof(unsigned char *);
561 _media_thumb_set_buffer(&req_msg, &buf, &buf_size);
563 if (send(sock, buf, buf_size, 0) != buf_size) {
564 thumb_err("sendto failed: %d", errno);
566 ms_ipc_delete_client_socket(&sock_info);
567 return MS_MEDIA_ERR_SOCKET_SEND;
570 thumb_dbg("Sending msg to thumbnail daemon is successful");
574 if ((err = _media_thumb_recv_msg(sock, header_size, &recv_msg)) < 0) {
575 thumb_err("_media_thumb_recv_msg failed ");
576 ms_ipc_delete_client_socket(&sock_info);
580 recv_str_len = strlen(recv_msg.org_path);
581 thumb_dbg_slog("recv %s(%d) from thumb daemon is successful", recv_msg.org_path, recv_str_len);
583 ms_ipc_delete_client_socket(&sock_info);
585 if (recv_str_len > max_length) {
586 thumb_err("user buffer is too small. Output's length is %d", recv_str_len);
587 SAFE_FREE(recv_msg.thumb_data);
588 return MS_MEDIA_ERR_INVALID_PARAMETER;
591 if (recv_msg.status == THUMB_FAIL) {
592 thumb_err("Failed to make thumbnail");
593 SAFE_FREE(recv_msg.thumb_data);
594 return MS_MEDIA_ERR_INVALID_PARAMETER;
597 if (msg_type != THUMB_REQUEST_SAVE_FILE) {
598 strncpy(thumb_path, recv_msg.dst_path, max_length);
601 thumb_info->origin_width = recv_msg.origin_width;
602 thumb_info->origin_height = recv_msg.origin_height;
604 SAFE_FREE(recv_msg.thumb_data);
606 return MS_MEDIA_ERR_NONE;
609 gboolean _media_thumb_write_socket(GIOChannel *src, GIOCondition condition, gpointer data)
615 int err = MS_MEDIA_ERR_NONE;
617 memset((void *)&recv_msg, 0, sizeof(thumbMsg));
618 sock = g_io_channel_unix_get_fd(src);
620 header_size = sizeof(thumbMsg) - MAX_PATH_SIZE*2 - sizeof(unsigned char *);
622 thumb_err("_media_thumb_write_socket socket : %d", sock);
624 if ((err = _media_thumb_recv_msg(sock, header_size, &recv_msg)) < 0) {
625 thumb_err("_media_thumb_recv_msg failed ");
626 if (recv_msg.origin_path_size > 0) {
627 __media_thumb_pop_req_queue(recv_msg.org_path, TRUE);
629 thumb_err("origin path size is wrong.");
635 g_io_channel_shutdown(src, TRUE, NULL);
636 g_io_channel_unref(src);
637 //thumb_dbg("Completed..%s", recv_msg.org_path);
639 if (recv_msg.status == THUMB_FAIL) {
640 thumb_err("Failed to make thumbnail");
641 err = MS_MEDIA_ERR_INTERNAL;
644 if(__media_thumb_check_cancel()) {
646 thumbUserData* cb = (thumbUserData*)data;
647 if (cb->func != NULL)
648 cb->func(err, recv_msg.dst_path, cb->user_data);
652 __media_thumb_pop_req_queue(recv_msg.org_path, FALSE);
656 SAFE_FREE(recv_msg.thumb_data);
658 /* Check manage queue */
660 len = g_queue_get_length(g_manage_queue);
663 _media_thumb_send_request();
665 g_queue_free(g_manage_queue);
666 g_manage_queue = NULL;
673 gboolean _media_thumb_raw_data_write_socket(GIOChannel *src, GIOCondition condition, gpointer data)
679 int err = MS_MEDIA_ERR_NONE;
681 memset((void *)&recv_msg, 0, sizeof(thumbMsg));
682 sock = g_io_channel_unix_get_fd(src);
684 header_size = sizeof(thumbMsg) - MAX_PATH_SIZE*2 - sizeof(unsigned char *);
686 thumb_err("_media_thumb_write_socket socket : %d", sock);
688 if ((err = _media_thumb_recv_msg(sock, header_size, &recv_msg)) < 0) {
689 thumb_err("_media_thumb_recv_msg failed ");
690 if (recv_msg.request_id > 0) {
691 __media_thumb_pop_raw_data_req_queue(recv_msg.request_id, TRUE);
693 thumb_err("origin path size is wrong.");
699 g_io_channel_shutdown(src, TRUE, NULL);
700 g_io_channel_unref(src);
702 if (recv_msg.status == THUMB_FAIL) {
703 thumb_err("Failed to make thumbnail");
704 err = MS_MEDIA_ERR_INTERNAL;
707 if(__media_thumb_check_cancel_for_raw()) {
709 thumbRawUserData* cb = (thumbRawUserData*)data;
710 if (cb->func != NULL)
711 cb->func(err, recv_msg.request_id, recv_msg.org_path, recv_msg.thumb_width, recv_msg.thumb_height, recv_msg.thumb_data, recv_msg.thumb_size, cb->user_data);
715 __media_thumb_pop_raw_data_req_queue(recv_msg.request_id, FALSE);
719 SAFE_FREE(recv_msg.thumb_data);
721 /* Check manage queue */
722 if(g_manage_raw_queue) {
723 len = g_queue_get_length(g_manage_raw_queue);
726 _media_thumb_raw_data_send_request();
728 g_queue_free(g_manage_raw_queue);
729 g_manage_raw_queue = NULL;
736 int _media_thumb_send_request() {
737 int err = MS_MEDIA_ERR_NONE;
739 struct sockaddr_un serv_addr;
740 ms_sock_info_s sock_info;
741 thumbReq *req_manager = NULL;
743 sock_info.port = MS_THUMB_CREATOR_PORT;
745 err = ms_ipc_create_client_socket(MS_PROTOCOL_TCP, MS_TIMEOUT_SEC_10, &sock_info);
746 if(err != MS_MEDIA_ERR_NONE)
748 thumb_err("ms_ipc_create_client_socket failed");
752 memset(&serv_addr, 0, sizeof(serv_addr));
753 sock = sock_info.sock_fd;
754 serv_addr.sun_family = AF_UNIX;
755 strcpy(serv_addr.sun_path, "/var/run/media-server/media_ipc_thumbcreator.socket");
757 GIOChannel *channel = NULL;
758 channel = g_io_channel_unix_new(sock);
761 /* Connecting to the thumbnail server */
762 if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
763 thumb_stderror("connect");
764 g_io_channel_shutdown(channel, TRUE, NULL);
765 g_io_channel_unref(channel);
766 return MS_MEDIA_ERR_SOCKET_CONN;
768 req_manager = (thumbReq *)g_queue_pop_head(g_manage_queue);
769 GSource *source = NULL;
770 source = g_io_create_watch(channel, G_IO_IN);
771 g_source_set_callback(source, (GSourceFunc)_media_thumb_write_socket, req_manager->userData, NULL);
772 source_id = g_source_attach(source, g_main_context_get_thread_default());
776 memset((void *)&req_msg, 0, sizeof(thumbMsg));
780 req_msg.msg_type = req_manager->msg_type;
781 req_msg.request_id = 0;
782 req_msg.uid = req_manager->uid;
783 strncpy(req_msg.org_path, req_manager->path, sizeof(req_msg.org_path));
784 req_msg.org_path[strlen(req_msg.org_path)] = '\0';
785 req_msg.dst_path[0] = '\0';
786 req_msg.origin_path_size = strlen(req_msg.org_path) + 1;
787 req_msg.dest_path_size = 1;
788 req_msg.thumb_size = 0;
790 if (req_msg.origin_path_size > MAX_PATH_SIZE || req_msg.dest_path_size > MAX_PATH_SIZE) {
791 thumb_err("path's length exceeds %d", MAX_PATH_SIZE);
792 g_io_channel_shutdown(channel, TRUE, NULL);
793 g_io_channel_unref(channel);
794 ms_ipc_delete_client_socket(&sock_info);
795 return MS_MEDIA_ERR_INVALID_PARAMETER;
798 unsigned char *buf = NULL;
800 _media_thumb_set_buffer(&req_msg, &buf, &buf_size);
802 if (send(sock, buf, buf_size, 0) != buf_size) {
803 thumb_err("sendto failed: %d", errno);
805 g_source_destroy(g_main_context_find_source_by_id(g_main_context_get_thread_default(), source_id));
806 g_io_channel_shutdown(channel, TRUE, NULL);
807 g_io_channel_unref(channel);
808 ms_ipc_delete_client_socket(&sock_info);
809 return MS_MEDIA_ERR_SOCKET_SEND;
813 thumb_dbg("Sending msg to thumbnail daemon is successful");
816 if (req_manager->msg_type == THUMB_REQUEST_DB_INSERT) {
817 if (g_request_queue == NULL) {
818 g_request_queue = g_queue_new();
821 thumbReq *thumb_req = NULL;
822 THUMB_MALLOC(thumb_req, sizeof(thumbReq));
823 if (thumb_req == NULL) {
824 thumb_err("Failed to create request element");
825 return MS_MEDIA_ERR_INVALID_PARAMETER;
828 thumb_req->channel = channel;
829 thumb_req->path = strdup(req_manager->path);
830 thumb_req->source_id = source_id;
831 thumb_req->userData = req_manager->userData;
833 g_queue_push_tail(g_request_queue, (gpointer)thumb_req);
839 int _media_thumb_raw_data_send_request() {
840 int err = MS_MEDIA_ERR_NONE;
842 struct sockaddr_un serv_addr;
843 ms_sock_info_s sock_info;
844 thumbRawReq *req_manager = NULL;
846 sock_info.port = MS_THUMB_CREATOR_PORT;
848 err = ms_ipc_create_client_socket(MS_PROTOCOL_TCP, MS_TIMEOUT_SEC_10, &sock_info);
849 if(err != MS_MEDIA_ERR_NONE)
851 thumb_err("ms_ipc_create_client_socket failed");
855 memset(&serv_addr, 0, sizeof(serv_addr));
856 sock = sock_info.sock_fd;
857 serv_addr.sun_family = AF_UNIX;
858 strcpy(serv_addr.sun_path, "/var/run/media-server/media_ipc_thumbcreator.socket");
860 GIOChannel *channel = NULL;
861 channel = g_io_channel_unix_new(sock);
864 /* Connecting to the thumbnail server */
865 if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
866 thumb_stderror("connect error");
867 g_io_channel_shutdown(channel, TRUE, NULL);
868 g_io_channel_unref(channel);
869 return MS_MEDIA_ERR_SOCKET_CONN;
872 req_manager = (thumbRawReq *)g_queue_pop_head(g_manage_raw_queue);
873 GSource *source = NULL;
874 source = g_io_create_watch(channel, G_IO_IN);
875 g_source_set_callback(source, (GSourceFunc)_media_thumb_raw_data_write_socket, req_manager->userData, NULL);
876 source_id = g_source_attach(source, g_main_context_get_thread_default());
879 memset((void *)&req_msg, 0, sizeof(thumbMsg));
883 req_msg.msg_type = req_manager->msg_type;
884 req_msg.request_id = req_manager->request_id;
885 req_msg.thumb_width = req_manager->width;
886 req_msg.thumb_height = req_manager->height;
887 req_msg.uid = req_manager->uid;
889 strncpy(req_msg.org_path, req_manager->path, sizeof(req_msg.org_path));
890 req_msg.org_path[strlen(req_msg.org_path)] = '\0';
891 req_msg.dst_path[0] = '\0';
893 req_msg.origin_path_size = strlen(req_msg.org_path) + 1;
894 req_msg.dest_path_size = 1;
895 req_msg.thumb_size = 0;
897 if (req_msg.origin_path_size > MAX_PATH_SIZE) {
898 thumb_err("path's length exceeds %d", MAX_PATH_SIZE);
899 g_io_channel_shutdown(channel, TRUE, NULL);
900 g_io_channel_unref(channel);
901 return MS_MEDIA_ERR_INVALID_PARAMETER;
904 unsigned char *buf = NULL;
906 _media_thumb_set_buffer(&req_msg, &buf, &buf_size);
908 if (send(sock, buf, buf_size, 0) != buf_size) {
909 thumb_err("sendto failed: %d", errno);
911 g_source_destroy(g_main_context_find_source_by_id(g_main_context_get_thread_default(), source_id));
912 g_io_channel_shutdown(channel, TRUE, NULL);
913 g_io_channel_unref(channel);
914 return MS_MEDIA_ERR_SOCKET_SEND;
919 if (req_manager->msg_type == THUMB_REQUEST_RAW_DATA) {
920 if (g_request_raw_queue == NULL) {
921 g_request_raw_queue = g_queue_new();
923 thumbRawReq *thumb_req = NULL;
924 THUMB_MALLOC(thumb_req, sizeof(thumbRawReq));
925 if (thumb_req == NULL) {
926 thumb_err("Failed to create request element");
927 return MS_MEDIA_ERR_INVALID_PARAMETER;
929 thumb_req->channel = channel;
930 thumb_req->request_id = req_manager->request_id;
931 thumb_req->source_id = source_id;
932 thumb_req->userData = req_manager->userData;
934 g_queue_push_tail(g_request_raw_queue, (gpointer)thumb_req);
936 return MS_MEDIA_ERR_NONE;
939 int _media_thumb_request_async(int msg_type, const char *origin_path, thumbUserData *userData, uid_t uid)
941 int err = MS_MEDIA_ERR_NONE;
943 if(g_manage_queue == NULL) {
944 if(msg_type == THUMB_REQUEST_CANCEL_MEDIA)
945 return MS_MEDIA_ERR_INTERNAL;
947 g_manage_queue = g_queue_new();
949 thumbReq *thumb_req = NULL;
950 THUMB_MALLOC(thumb_req, sizeof(thumbReq));
951 if (thumb_req == NULL) {
952 thumb_err("Failed to create request element");
953 return MS_MEDIA_ERR_INVALID_PARAMETER;
956 thumb_req->msg_type = msg_type;
957 thumb_req->path = strdup(origin_path);
958 thumb_req->userData = userData;
959 thumb_req->isCanceled = false;
960 thumb_req->uid = uid;
962 g_queue_push_tail(g_manage_queue, (gpointer)thumb_req);
964 /* directly request at first time */
965 err = _media_thumb_send_request();
968 if(msg_type != THUMB_REQUEST_CANCEL_MEDIA) {
970 if ((msg_type == THUMB_REQUEST_DB_INSERT) && (__media_thumb_check_req_queue(origin_path) < 0)) {
971 thumb_err("duplicated request");
972 return MS_MEDIA_ERR_THUMB_DUPLICATED_REQUEST;
975 thumbReq *thumb_req = NULL;
976 THUMB_MALLOC(thumb_req, sizeof(thumbReq));
977 if (thumb_req == NULL) {
978 thumb_err("Failed to create request element");
979 return MS_MEDIA_ERR_INVALID_PARAMETER;
982 thumb_req->msg_type = msg_type;
983 thumb_req->path = strdup(origin_path);
984 thumb_req->userData = userData;
985 thumb_req->isCanceled = false;
986 thumb_req->uid = uid;
988 g_queue_push_tail(g_manage_queue, (gpointer)thumb_req);
991 err = __media_thumb_pop_manage_queue(origin_path);
998 int _media_thumb_request_raw_data_async(int msg_type, int request_id, const char *origin_path, int width, int height, thumbRawUserData *userData, uid_t uid)
1000 int err = MS_MEDIA_ERR_NONE;
1002 if(g_manage_raw_queue == NULL) {
1003 if(msg_type == THUMB_REQUEST_CANCEL_RAW_DATA)
1004 return MS_MEDIA_ERR_INTERNAL;
1006 g_manage_raw_queue = g_queue_new();
1008 thumbRawReq *thumb_req = NULL;
1009 THUMB_MALLOC(thumb_req, sizeof(thumbRawReq));
1010 if (thumb_req == NULL) {
1011 thumb_err("Failed to create request element");
1012 return MS_MEDIA_ERR_INVALID_PARAMETER;
1015 thumb_req->msg_type = msg_type;
1016 thumb_req->request_id = request_id;
1017 thumb_req->path = strdup(origin_path);
1018 thumb_req->width = width;
1019 thumb_req->height= height;
1020 thumb_req->userData = userData;
1021 thumb_req->isCanceled = false;
1022 thumb_req->uid = uid;
1024 g_queue_push_tail(g_manage_raw_queue, (gpointer)thumb_req);
1026 /* directly request at first time */
1027 err = _media_thumb_raw_data_send_request();
1030 if(msg_type != THUMB_REQUEST_CANCEL_RAW_DATA) {
1032 thumbRawReq *thumb_req = NULL;
1033 THUMB_MALLOC(thumb_req, sizeof(thumbRawReq));
1034 if (thumb_req == NULL) {
1035 thumb_err("Failed to create request element");
1036 return MS_MEDIA_ERR_INVALID_PARAMETER;
1039 thumb_req->msg_type = msg_type;
1040 thumb_req->request_id = request_id;
1041 thumb_req->path = strdup(origin_path);
1042 thumb_req->width = width;
1043 thumb_req->height= height;
1044 thumb_req->userData = userData;
1045 thumb_req->isCanceled = false;
1046 thumb_req->uid = uid;
1048 g_queue_push_tail(g_manage_raw_queue, (gpointer)thumb_req);
1052 err = __media_thumb_pop_raw_data_manage_queue(request_id);
1059 int _media_thumb_request_cancel_all(bool isRaw) {
1065 thumbRawReq *tmp_raw_req = NULL;
1066 if(g_manage_raw_queue == NULL) {
1067 thumb_err("manage_queue is NULL");
1068 if(g_request_raw_queue != NULL) {
1069 /* Check request queue */
1070 len = g_queue_get_length(g_request_raw_queue);
1072 tmp_raw_req = g_queue_peek_head(g_request_raw_queue);
1073 if (tmp_raw_req != NULL)
1074 tmp_raw_req->isCanceled = true;
1075 return MS_MEDIA_ERR_NONE;
1078 thumb_err("request_queue is NULL");
1079 return MS_MEDIA_ERR_INTERNAL;
1081 req_len = g_queue_get_length(g_manage_raw_queue);
1082 for(i=0;i<req_len;i++) {
1083 tmp_raw_req = g_queue_pop_tail(g_manage_raw_queue);
1085 SAFE_FREE(tmp_raw_req->path);
1086 SAFE_FREE(tmp_raw_req->userData);
1087 SAFE_FREE(tmp_raw_req);
1091 g_queue_free (g_manage_raw_queue);
1092 g_manage_raw_queue = NULL;
1093 if(g_request_raw_queue != NULL) {
1094 /* Check request queue */
1095 len = g_queue_get_length(g_request_raw_queue);
1097 tmp_raw_req = g_queue_peek_head(g_request_raw_queue);
1098 if (tmp_raw_req != NULL)
1099 tmp_raw_req->isCanceled = true;
1103 thumbReq *tmp_req = NULL;
1104 if(g_manage_queue == NULL) {
1105 thumb_err("manage_queue is NULL");
1106 if(g_request_queue != NULL) {
1107 /* Check request queue */
1108 len = g_queue_get_length(g_request_queue);
1110 tmp_req = g_queue_peek_head(g_request_queue);
1111 if (tmp_req != NULL)
1112 tmp_req->isCanceled = true;
1113 return MS_MEDIA_ERR_NONE;
1116 thumb_err("request_queue is NULL");
1117 return MS_MEDIA_ERR_INTERNAL;
1119 req_len = g_queue_get_length(g_manage_queue);
1120 for(i=0;i<req_len;i++) {
1121 tmp_req = g_queue_pop_tail(g_manage_queue);
1123 SAFE_FREE(tmp_req->path);
1124 SAFE_FREE(tmp_req->userData);
1129 g_queue_free (g_manage_queue);
1130 g_manage_queue = NULL;
1131 if(g_request_queue != NULL) {
1132 /* Check request queue */
1133 len = g_queue_get_length(g_request_queue);
1135 tmp_req = g_queue_peek_head(g_request_queue);
1136 if (tmp_req != NULL)
1137 tmp_req->isCanceled = true;
1142 return MS_MEDIA_ERR_NONE;