fix socket time out , no content occur
[platform/core/multimedia/media-server.git] / src / scanner-v2 / media-scanner-extract-v2.c
1 /*
2  * Media Server
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Yong Yeon Kim <yy9875.kim@samsung.com>
7  *
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
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22 #include <dirent.h>     /* Defines DT_* constants */
23 #include <fcntl.h>
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <stdlib.h>
27 #include <sys/stat.h>
28 #include <sys/syscall.h>
29
30 #include <dirent.h>
31 #include <malloc.h>
32 #include <vconf.h>
33
34 #include "media-util.h"
35 #include "media-server-ipc.h"
36 #include "media-common-utils.h"
37 #include "media-common-db-svc.h"
38 #include "media-scanner-dbg-v2.h"
39 #include "media-scanner-common-v2.h"
40 #include "media-scanner-db-manage-v2.h"
41 #include "media-scanner-socket-v2.h"
42 #include "media-scanner-extract-v2.h"
43
44 extern bool power_off2;
45 GAsyncQueue *storage_extract_queue;
46 GAsyncQueue *folder_extract_queue;
47 GMutex extract_req_mutex;
48 GMutex extract_blocked_mutex;
49 char *g_extract_cancel_path;
50 char *g_extract_blocked_path;
51 bool g_directory_extract_processing;
52 int stg_extract_status;
53
54 GMutex extract_item_mutex;
55 s_extract_item* cancel_extract_item = NULL;
56 s_extract_item* cur_extract_item = NULL;
57
58 GCond extract_data_cond;
59 GMutex extract_data_mutex;
60 #define VCONFKEY_PRIVATE_EXTRACTSTATUS "db/private/extractstatus"
61 #define LAST_EVENT 1
62 #define NORMAL_EVENT 0
63
64 static int __msc_check_extract_stop_status(int scan_type, ms_storage_type_t storage_type, const char *start_path, int pid, bool is_end);
65 static int __msc_set_storage_extract_status(ms_storage_scan_status_e status);
66 static int __msc_get_storage_extract_status(ms_storage_scan_status_e *status);
67 static int __msc_resume_extract();
68 static int __msc_pause_extract();
69 static int __msc_extract_set_db_status(ms_db_status_type_t status);
70
71 typedef struct {
72         int media_type;
73         char *path;
74 } ms_item_info_s;
75
76 static int __msc_folder_bulk_extract(void **handle, const char* storage_id, int storage_type, const char *path, int scan_type, int burst, int pid, uid_t uid, unsigned int *io_err_count, bool is_end);
77
78 int msc_init_extract_thread()
79 {
80         if (!storage_extract_queue) storage_extract_queue = g_async_queue_new();
81         if (!folder_extract_queue) folder_extract_queue = g_async_queue_new();
82
83         g_mutex_init(&extract_req_mutex);
84         g_mutex_init(&extract_blocked_mutex);
85         g_mutex_init(&extract_data_mutex);
86
87         g_mutex_init(&extract_item_mutex);
88
89         g_cond_init(&extract_data_cond);
90
91         return MS_MEDIA_ERR_NONE;
92 }
93
94 int msc_deinit_extract_thread()
95 {
96         if (storage_extract_queue) g_async_queue_unref(storage_extract_queue);
97         if (folder_extract_queue) g_async_queue_unref(folder_extract_queue);
98
99         g_mutex_clear(&extract_req_mutex);
100         g_mutex_clear(&extract_blocked_mutex);
101         g_mutex_clear(&extract_data_mutex);
102
103         g_mutex_clear(&extract_item_mutex);
104
105         g_cond_clear(&extract_data_cond);
106
107         return MS_MEDIA_ERR_NONE;
108 }
109
110 int __msc_folder_bulk_extract(void **handle, const char* storage_id, int storage_type, const char *path, int scan_type, int burst, int pid, uid_t uid, unsigned int *io_err_count, bool is_end)
111 {
112         MS_DBG_WARN("begin of __msc_folder_bulk_extract");
113         int ret = MS_MEDIA_ERR_NONE;
114         int tmp_ret = MS_MEDIA_ERR_NONE;
115         GArray *data_array = NULL;
116         ms_item_info_s* db_data = NULL;
117         int extract_count = 0;
118
119         ret = ms_get_extract_list(handle, storage_id, storage_type, scan_type, path, burst, uid, (void*)&data_array);
120         if (ret != MS_MEDIA_ERR_NONE) {
121                 MS_DBG_ERR("ms_get_extract_list failed!!!");
122                 return MS_MEDIA_ERR_NONE;
123         }
124
125         if (data_array == NULL) {
126                 MS_DBG_ERR("data_array is NULL!!!");
127                 return MS_MEDIA_ERR_NONE;
128         }
129
130         while (data_array->len != 0) {
131                 tmp_ret = MS_MEDIA_ERR_NONE;
132                 db_data = NULL;
133
134                 ret = __msc_check_extract_stop_status(scan_type, storage_type, path, pid, is_end);
135                 if (ret == MS_MEDIA_ERR_SCANNER_FORCE_STOP) {
136                         MS_DBG_ERR("__msc_folder_bulk_extract MS_MEDIA_ERR_SCANNER_FORCE_STOP");
137                         break;
138                 }
139
140                 db_data = g_array_index(data_array, ms_item_info_s*, 0);
141                 g_array_remove_index(data_array, 0);
142
143                 tmp_ret = ms_update_one_extract_item(handle, storage_id, storage_type, db_data, burst);
144                 if (tmp_ret == MS_MEDIA_ERR_NONE)
145                         extract_count++;
146                 else if (tmp_ret == MS_MEDIA_ERR_FILE_IO)
147                         (*io_err_count)++;
148
149                 if (db_data) {
150                         MS_SAFE_FREE(db_data->path);
151                         MS_SAFE_FREE(db_data);
152                         db_data = NULL;
153                 }
154         }
155
156         if (extract_count > 0)
157                 ms_query_do_update_list(handle);
158
159         while (data_array->len != 0) {
160                 db_data = NULL;
161                 db_data = g_array_index(data_array, ms_item_info_s*, 0);
162                 g_array_remove_index(data_array, 0);
163
164                 if (db_data) {
165                         MS_SAFE_FREE(db_data->path);
166                         MS_SAFE_FREE(db_data);
167                         db_data = NULL;
168                 }
169         }
170         g_array_free(data_array, FALSE);
171         data_array = NULL;
172
173         MS_DBG_WARN("end of __msc_folder_bulk_extract");
174         return ret;
175 }
176
177 gboolean msc_folder_extract_thread(void *data)
178 {
179         ms_comm_msg_s *extract_data = NULL;
180         int ret = MS_MEDIA_ERR_NONE;
181         void **handle = NULL;
182         int scan_type;
183         ms_user_storage_type_e storage_type;
184         char *storage_id = NULL;
185         char *update_path = NULL;
186         unsigned int io_err_count = 0;
187         uid_t uid = MEDIA_DEFAULT_UID;
188         int disc_state = 0;
189         int end_flag = NORMAL_EVENT;
190
191         while (1) {
192                 extract_data = g_async_queue_pop(folder_extract_queue);
193                 if (extract_data->pid == POWEROFF) {
194                         MS_DBG_ERR("power off");
195                         goto _POWEROFF;
196                 }
197
198                 MS_DBG_WARN("DIRECTORY EXTRACT START [%s %d]", extract_data->msg, extract_data->msg_type);
199
200                 io_err_count = 0;
201
202                 msc_set_cur_extract_item(extract_data->msg, extract_data->pid);
203                 g_directory_extract_processing = true;
204                 uid = extract_data->uid;
205
206                 /*connect to media db, if conneting is failed, db updating is stopped*/
207                 ret = ms_connect_db(&handle, uid);
208                 if (ret != MS_MEDIA_ERR_NONE) {
209                         MS_DBG_ERR("ms_connect_db failed");
210                         goto NEXT;
211                 }
212
213                 scan_type = extract_data->msg_type;
214
215                 storage_id = strdup(extract_data->storage_id);
216                 if (storage_id == NULL) {
217                         MS_DBG_ERR("storage_id NULL");
218                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
219                         goto NEXT;
220                 }
221
222                 MS_DBG("path : [%s], storage_id : [%s]", extract_data->msg, storage_id);
223
224                 update_path = strndup(extract_data->msg, extract_data->msg_size);
225
226                 if (strlen(storage_id) == 0) {
227                         MS_DBG_ERR("storage_id length is 0. There is no information of your request [%s]", extract_data->msg);
228                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
229                         goto NEXT;
230                 }
231
232                 if (scan_type != MS_MSG_DIRECTORY_SCANNING
233                         && scan_type != MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
234                         MS_DBG_ERR("Invalid request");
235                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
236                         goto NEXT;
237                 }
238                 end_flag = extract_data->result ? LAST_EVENT : NORMAL_EVENT;
239
240                 ret = ms_user_get_storage_type(uid, extract_data->msg, &storage_type);
241                 if (ret != MS_MEDIA_ERR_NONE) {
242                         MS_DBG_ERR("ms_user_get_storage_type failed");
243                         goto NEXT;
244                 }
245
246                 ret = __msc_check_extract_stop_status(extract_data->msg_type, storage_type, update_path, extract_data->pid, end_flag);
247
248                 if (ret == MS_MEDIA_ERR_SCANNER_FORCE_STOP) {
249                         MS_DBG_ERR("MS_MEDIA_ERR_SCANNER_FORCE_STOP");
250                         goto NEXT;
251                 }
252
253                 /*insert data into media db */
254                 ret = msc_check_db_size(uid, extract_data->msg_type);
255                 if (ret != MS_MEDIA_ERR_NONE) {
256                         MS_DBG_ERR("NOT ENOUGH MEMORY");
257                         if (ret == MS_MEDIA_ERR_DB_FULL_FAIL)
258                                 ret = MS_MEDIA_ERR_NONE;
259
260                         goto NEXT;
261                 }
262
263                 ret = __msc_folder_bulk_extract(handle, extract_data->storage_id, storage_type, update_path, scan_type, end_flag, extract_data->pid, uid, &io_err_count, end_flag);
264
265 NEXT:
266                 g_directory_extract_processing = false;
267                 if (power_off2) {
268                         MS_DBG_ERR("power off");
269                         goto _POWEROFF;
270                 }
271
272                 /*Active flush */
273                 malloc_trim(0);
274
275                 if (extract_data->result) {
276                         /*send notification*/
277                         char *folder_uuid = NULL;
278                         ms_get_folder_id(handle, storage_id, extract_data->msg, &folder_uuid);
279                         ms_send_dir_update_noti(handle, storage_id, update_path, folder_uuid, MS_ITEM_UPDATE, extract_data->pid);
280                         extract_data->msg_type = MS_MSG_EXTRACTOR_COMPLETE;
281                         msc_send_result(ret, extract_data);
282                 }
283
284                 MS_SAFE_FREE(update_path);
285                 MS_SAFE_FREE(extract_data);
286                 MS_SAFE_FREE(storage_id);
287
288                 msc_del_cur_extract_item();
289                 msc_del_cancel_extract_item();
290                 if (msc_get_disc_dir_scan_status()) {
291                         MS_DBG("[DISC ACCESS END]");
292                         msc_set_disc_dir_scan_status(false);
293
294                         ms_config_get_int(MS_DISC_ACCESS_STATE, &disc_state);
295                         if (disc_state == MS_DISC_ACCESS) {
296                                 MS_DBG("[CHANGE DISC STATE]");
297                                 ms_config_set_int(MS_DISC_ACCESS_STATE, MS_DISC_NOT_ACCESS);
298                         }
299                 }
300
301                 MS_DBG_WARN("DIRECTORY EXTRACT END [%d]", ret);
302
303                 ms_storage_scan_status_e storage_scan_status = MS_STORAGE_SCAN_NONE;
304                 ret = __msc_get_storage_extract_status(&storage_scan_status);
305                 if (ret == MS_MEDIA_ERR_NONE) {
306                         /*get storage list and scan status from media db*/
307                         if (storage_scan_status != MS_STORAGE_SCAN_COMPLETE) {
308                                 __msc_resume_extract();
309                                 MS_DBG_WARN("extract RESUME OK");
310                         }
311                 }
312
313                 /*disconnect form media db*/
314                 if (handle) ms_disconnect_db(&handle);
315         }                       /*thread while*/
316
317 _POWEROFF:
318         __msc_resume_extract();
319
320         MS_SAFE_FREE(update_path);
321         MS_SAFE_FREE(extract_data);
322         MS_SAFE_FREE(storage_id);
323
324         if (handle) ms_disconnect_db(&handle);
325
326         return false;
327 }
328
329 gboolean msc_storage_extract_thread(void *data)
330 {
331         ms_comm_msg_s *extract_data = NULL;
332         int ret = MS_MEDIA_ERR_NONE;
333         void **handle = NULL;
334         ms_user_storage_type_e storage_type = MS_STORAGE_INTERNAL;
335         int scan_type;
336         char *update_path = NULL;
337         unsigned int io_err_count = 0;
338         uid_t uid = MEDIA_DEFAULT_UID;
339         int disc_state = 0;
340         int end_flag = NORMAL_EVENT;
341
342         while (1) {
343                 __msc_set_storage_extract_status(MS_STORAGE_SCAN_DONE);
344                 extract_data = g_async_queue_pop(storage_extract_queue);
345                 if (extract_data->pid == POWEROFF) {
346                         MS_DBG_ERR("power off");
347                         goto _POWEROFF;
348                 }
349
350                 __msc_set_storage_extract_status(MS_STORAGE_SCAN_META_PROCESSING);
351
352                 io_err_count = 0;
353
354                 MS_DBG_WARN("STORAGE extract START extract len is %d ", g_async_queue_length(storage_extract_queue));
355
356                 scan_type = extract_data->msg_type;
357                 if (scan_type != MS_MSG_STORAGE_ALL
358                         && scan_type != MS_MSG_STORAGE_PARTIAL) {
359                         MS_DBG_ERR("Invalid request[%d]", scan_type);
360                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
361                         goto NEXT;
362                 }
363
364                 uid = extract_data->uid;
365
366                 /*connect to media db, if conneting is failed, db updating is stopped*/
367                 ret = ms_connect_db(&handle, uid);
368                 if (ret != MS_MEDIA_ERR_NONE) {
369                         MS_DBG_ERR("ms_connect_db falied!");
370                         continue;
371                 }
372
373                 end_flag = extract_data->result ? LAST_EVENT : NORMAL_EVENT;
374                 update_path = g_strndup(extract_data->msg, extract_data->msg_size);
375                 if (!MS_STRING_VALID(update_path)) {
376                         MS_DBG_ERR("Invalid update_path");
377                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
378                         goto NEXT;
379                 }
380                 MS_DBG_WARN("extract storage_id is [%s], path [%s]", extract_data->storage_id, update_path);
381                 ret = ms_user_get_storage_type(uid, extract_data->msg, &storage_type);
382                 if (ret != MS_MEDIA_ERR_NONE) {
383                         MS_DBG_ERR("ms_user_get_storage_type failed");
384                         goto NEXT;
385                 }
386                 if (storage_type == MS_STORAGE_EXTERNAL_USB) {
387                         if (!ms_storage_mount_status(update_path)) {
388                                 MS_DBG_ERR("%s is unmounted", update_path);
389                                 ret = MS_MEDIA_ERR_USB_UNMOUNTED;
390                                 msc_remove_extract_request(extract_data);
391                                 goto NEXT;
392                         }
393                 }
394                 ms_set_storage_scan_status(handle, extract_data->storage_id, MEDIA_EXTRACT_PROCESSING, uid);
395                 __msc_extract_set_db_status(MS_DB_UPDATING);
396
397                 ret = msc_check_db_size(uid, extract_data->msg_type);
398                 if (ret != MS_MEDIA_ERR_NONE) {
399                         MS_DBG_ERR("NOT ENOUGH MEMORY");
400                         __msc_extract_set_db_status(MS_DB_STOPPED);
401                         if (strncmp(update_path, MEDIA_ROOT_PATH_DISC, strlen(MEDIA_ROOT_PATH_DISC)) == 0) {
402                                 if (msc_get_disc_stg_scan_status()) {
403                                         MS_DBG("[DISC ACCESS STOP]");
404                                         msc_set_disc_stg_scan_status(false);
405
406                                         ms_config_get_int(MS_DISC_ACCESS_STATE, &disc_state);
407                                         if (disc_state == MS_DISC_ACCESS) {
408                                                 MS_DBG("[CHANGE DISC STATE]");
409                                                 ms_config_set_int(MS_DISC_ACCESS_STATE, MS_DISC_NOT_ACCESS);
410                                         }
411                                 }
412                         }
413
414                         goto NEXT;
415                 }
416
417                 /*extract meta*/
418                 ret = __msc_folder_bulk_extract(handle, extract_data->storage_id, storage_type, update_path, scan_type, end_flag, extract_data->pid, uid, &io_err_count, end_flag);
419                 MS_DBG_WARN("extract PAUSE");
420                 __msc_pause_extract();
421                 MS_DBG_WARN("extract RESUME");
422
423                 int tem_ret = __msc_check_extract_stop_status(extract_data->msg_type, storage_type, update_path, extract_data->pid, end_flag);
424                 if (tem_ret == MS_MEDIA_ERR_SCANNER_FORCE_STOP) {
425                         ms_set_storage_scan_status(handle, extract_data->storage_id, MEDIA_EXTRACT_STOP, uid);
426                         __msc_set_storage_extract_status(MS_STORAGE_SCAN_META_STOP);
427                         MS_DBG_WARN("storage scan force stopped");
428                         /* set vconf key db extract status */
429                         __msc_extract_set_db_status(MS_DB_STOPPED);
430                         if (msc_get_disc_stg_scan_status()) {
431                                 MS_DBG("[DISC ACCESS STOP]");
432                                 msc_set_disc_stg_scan_status(false);
433
434                                 ms_config_get_int(MS_DISC_ACCESS_STATE, &disc_state);
435                                 if (disc_state == MS_DISC_ACCESS) {
436                                         MS_DBG("[CHANGE DISC STATE]");
437                                         ms_config_set_int(MS_DISC_ACCESS_STATE, MS_DISC_NOT_ACCESS);
438                                 }
439                         }
440                         msc_del_extract_blocked_path(update_path);
441                         msc_remove_extract_request(extract_data);
442                         goto NEXT;
443                 }
444                 if (extract_data->result == TRUE) {
445                         MS_DBG_WARN("extract_data->result == TRUE, MS_STORAGE_SCAN_COMPLETE");
446                         ms_set_storage_scan_status(handle, extract_data->storage_id, MEDIA_EXTRACT_COMPLETE, uid);
447                         __msc_set_storage_extract_status(MS_STORAGE_SCAN_COMPLETE);
448
449                         /* send notification */
450                         ms_send_dir_update_noti(handle, extract_data->storage_id, update_path, NULL, MS_ITEM_UPDATE, extract_data->pid);
451                         /* set vconf key db extract status */
452                         __msc_extract_set_db_status(MS_DB_UPDATED);
453                         if (msc_get_disc_stg_scan_status()) {
454                                 MS_DBG("[DISC ACCESS END]");
455                                 msc_set_disc_stg_scan_status(false);
456
457                                 ms_config_get_int(MS_DISC_ACCESS_STATE, &disc_state);
458                                 if (disc_state == MS_DISC_ACCESS) {
459                                         MS_DBG("[CHANGE DISC STATE]");
460                                         ms_config_set_int(MS_DISC_ACCESS_STATE, MS_DISC_NOT_ACCESS);
461                                 }
462
463                         }
464                 }
465 NEXT:
466                 MS_SAFE_FREE(update_path);
467
468                 if (power_off2) {
469                         MS_DBG_ERR("power off");
470                         goto _POWEROFF;
471                 }
472
473                 /*disconnect form media db*/
474                 if (handle) ms_disconnect_db(&handle);
475
476                 /*Active flush */
477                 malloc_trim(0);
478
479                 if (extract_data->result) {
480                         extract_data->msg_type = MS_MSG_EXTRACTOR_COMPLETE;
481                         msc_send_result(ret, extract_data);
482                 }
483
484                 MS_SAFE_FREE(extract_data);
485
486                 MS_DBG_WARN("STORAGE EXTRACT END[%d]", ret);
487         }                       /*thread while*/
488
489 _POWEROFF:
490         MS_SAFE_FREE(extract_data);
491         if (handle) ms_disconnect_db(&handle);
492
493         return false;
494 }
495
496 void msc_insert_exactor_request(int message_type, bool ins_status, const char *storage_id, const char *path, int pid, uid_t uid)
497 {
498         ms_comm_msg_s *extract_data = NULL;
499         MS_MALLOC(extract_data, sizeof(ms_comm_msg_s));
500         if (extract_data == NULL) {
501                 MS_DBG_ERR("MS_MALLOC failed");
502                 return;
503         }
504
505         extract_data->msg_type = message_type;
506         extract_data->pid = pid;
507         extract_data->uid = uid;
508         extract_data->result = ins_status;
509         extract_data->msg_size = strlen(path);
510         SAFE_STRLCPY(extract_data->msg, path, sizeof(extract_data->msg));
511         SAFE_STRLCPY(extract_data->storage_id, storage_id, sizeof(extract_data->storage_id));
512
513         if (message_type == MS_MSG_STORAGE_ALL || message_type == MS_MSG_STORAGE_PARTIAL || message_type == MS_MSG_STORAGE_INVALID) {
514                 g_async_queue_push(storage_extract_queue, GINT_TO_POINTER(extract_data));
515                 MS_DBG("insert to storage exactor queue. msg_type [%d]", ins_status);
516         } else if (message_type == MS_MSG_DIRECTORY_SCANNING || message_type == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
517                 g_async_queue_push(folder_extract_queue, GINT_TO_POINTER(extract_data));
518                 MS_DBG("insert to dir exactor queue. msg_type [%d]", ins_status);
519         } else {
520                 MS_DBG_ERR("try to insert to exactor scan with msg_type [%d]", message_type);
521                 MS_SAFE_FREE(extract_data);
522         }
523
524         return;
525 }
526
527 int msc_remove_extract_request(const ms_comm_msg_s *recv_msg)
528 {
529         if (recv_msg == NULL) {
530                 MS_DBG_ERR("recv_msg is null");
531                 return MS_MEDIA_ERR_INVALID_PARAMETER;
532         }
533         const char *storageid = recv_msg->storage_id;
534         int len = g_async_queue_length(storage_extract_queue);
535         ms_comm_msg_s *msg = NULL;
536         GAsyncQueue *temp_queue = NULL;
537
538         MS_DBG_WARN("exactor_req_mutex is LOCKED");
539         g_mutex_lock(&extract_req_mutex);
540
541         if (len <= 0) {
542                 MS_DBG_ERR("Request is not stacked");
543                 goto END_REMOVE_REQUEST;
544         }
545
546         temp_queue = g_async_queue_new();
547         int i = 0;
548         for (; i < len; i++) {
549                 /*create new queue to compare request*/
550                 msg = g_async_queue_pop(storage_extract_queue);
551                 if ((strcmp(msg->storage_id, storageid) == 0)) {
552                         if (msg->result) {
553                                 MS_DBG_WARN("force stop storage scan");
554                                 msg->msg_type = MS_MSG_EXTRACTOR_COMPLETE;
555                                 msc_send_result(MS_MEDIA_ERR_SCANNER_FORCE_STOP, msg);
556                         }
557                         MS_SAFE_FREE(msg);
558                 } else {
559                         g_async_queue_push(temp_queue, GINT_TO_POINTER(msg));
560                 }
561         }
562         len = g_async_queue_length(temp_queue);
563         int j = 0;
564         for (; j < len; j++) {
565                 msg = g_async_queue_pop(temp_queue);
566                 if (msg)
567                         g_async_queue_push(storage_extract_queue, GINT_TO_POINTER(msg));
568         }
569         g_async_queue_unref(temp_queue);
570
571 END_REMOVE_REQUEST:
572         g_mutex_unlock(&extract_req_mutex);
573         MS_DBG_WARN("exactor_req_mutex is UNLOCKED");
574
575         return MS_MEDIA_ERR_NONE;
576 }
577
578 int _msc_set_extract_item(s_extract_item** item, const char* path, int pid)
579 {
580         s_extract_item* extract_item = *item;
581         if (extract_item != NULL) {
582                 MS_SAFE_FREE(extract_item->path);
583                 extract_item->pid = -1;
584         } else {
585                 extract_item = (s_extract_item*)malloc(sizeof(s_extract_item));
586                 if (extract_item == NULL) {
587                         MS_DBG_ERR("malloc item failed");
588                         return MS_MEDIA_ERR_INTERNAL;
589                 }
590                 memset(extract_item, 0, sizeof(s_extract_item));
591         }
592
593         extract_item->path = strdup(path);
594         extract_item->pid = pid;
595         *item = extract_item;
596
597         MS_DBG_WARN("_msc_set_extract_item path[%s],pid[%d]", extract_item->path, extract_item->pid);
598         return MS_MEDIA_ERR_NONE;
599 }
600
601 int _msc_del_extract_item(s_extract_item** item)
602 {
603         if (*item != NULL) {
604                 MS_SAFE_FREE((*item)->path);
605                 MS_SAFE_FREE(*item);
606         }
607
608         return MS_MEDIA_ERR_NONE;
609 }
610
611 int msc_set_cancel_extract_item(const char* cancel_path, int pid)
612 {
613         int ret = -1;
614         MS_DBG_WARN("msc_set_cancel_extract_item begin");
615         g_mutex_lock(&extract_item_mutex);
616         if (cancel_path == NULL) {
617                 MS_DBG_ERR("cancel_path invalid...");
618                 return ret;
619         }
620
621         if (cur_extract_item && cur_extract_item->path) {
622                 if ((strcmp(cur_extract_item->path, cancel_path) == 0) && (pid == cur_extract_item->pid))
623                         ret = _msc_set_extract_item(&cancel_extract_item, cancel_path, pid);
624                 else if ((pid == -1) && (strncmp(cur_extract_item->path, cancel_path, strlen(cancel_path)) == 0))
625                         ret = _msc_set_extract_item(&cancel_extract_item, cancel_path, pid);
626         }
627         g_mutex_unlock(&extract_item_mutex);
628
629         MS_DBG_WARN("msc_set_cancel_extract_item end");
630         return ret;
631 }
632
633 int msc_del_cancel_extract_item()
634 {
635         int ret = -1;
636         g_mutex_lock(&extract_item_mutex);
637         ret = _msc_del_extract_item(&cancel_extract_item);
638         g_mutex_unlock(&extract_item_mutex);
639
640         return ret;
641 }
642
643 int msc_set_cur_extract_item(const char* cur_path, int pid)
644 {
645         int ret = -1;
646         g_mutex_lock(&extract_item_mutex);
647         ret = _msc_set_extract_item(&cur_extract_item, cur_path, pid);
648         g_mutex_unlock(&extract_item_mutex);
649
650         return ret;
651 }
652 int msc_del_cur_extract_item()
653 {
654         int ret = -1;
655         g_mutex_lock(&extract_item_mutex);
656         ret = _msc_del_extract_item(&cur_extract_item);
657         g_mutex_unlock(&extract_item_mutex);
658
659         return ret;
660 }
661
662 int msc_set_extract_blocked_path(const char *blocked_path)
663 {
664         MS_DBG_FENTER();
665
666         g_mutex_lock(&extract_blocked_mutex);
667
668         if (g_extract_blocked_path != NULL) {
669                 MS_DBG_ERR("g_extract_blocked_path is not NULL [%s]", g_extract_blocked_path);
670                 MS_SAFE_FREE(g_extract_blocked_path);
671         }
672
673         g_extract_blocked_path = strdup(blocked_path);
674
675         g_mutex_unlock(&extract_blocked_mutex);
676
677         MS_DBG_FLEAVE();
678
679         return MS_MEDIA_ERR_NONE;
680 }
681
682 int msc_del_extract_blocked_path(const char* blocked_path)
683 {
684         MS_DBG_FENTER();
685
686         g_mutex_lock(&extract_blocked_mutex);
687         if (blocked_path) {
688                 if (g_extract_blocked_path && (0 == strncmp(blocked_path, g_extract_blocked_path, strlen(blocked_path)))) {
689                         MS_DBG_ERR("g_extract_blocked_path is not NULL [%s]", g_extract_blocked_path);
690                         MS_SAFE_FREE(g_extract_blocked_path);
691                 }
692         } else {
693                 if (g_extract_blocked_path != NULL) {
694                         MS_DBG_ERR("g_extract_blocked_path is not NULL [%s]", g_extract_blocked_path);
695                         MS_SAFE_FREE(g_extract_blocked_path);
696                 }
697         }
698
699         g_mutex_unlock(&extract_blocked_mutex);
700
701         MS_DBG_FLEAVE();
702
703         return MS_MEDIA_ERR_NONE;
704 }
705
706 static int __msc_check_extract_stop_status(int scan_type, ms_storage_type_t storage_type, const char *start_path, int pid, bool is_end)
707 {
708         int ret = MS_MEDIA_ERR_NONE;
709
710         /*check poweroff status*/
711         if (power_off2) {
712                 MS_DBG_ERR("Power off");
713                 ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
714                 goto END;
715         }
716         if (strncmp(start_path, MEDIA_ROOT_PATH_DISC, strlen(MEDIA_ROOT_PATH_DISC)) == 0) {
717                 int disc_state = 0;
718                 ms_config_get_int(MS_DISC_STATE, &disc_state);
719                 if (disc_state == 0) {
720                         MS_DBG_ERR("[DISC IS NOT INSERTED]");
721                         ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
722                         goto END;
723                 }
724         }
725
726         if (scan_type == MS_MSG_DIRECTORY_SCANNING || scan_type == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
727                 g_mutex_lock(&extract_req_mutex);
728                 /* check cancel path */
729                 //MS_DBG_ERR("__msc_check_extract_stop_status...");
730                 if ((cancel_extract_item != NULL) && (cancel_extract_item->path != NULL)) {
731                         MS_DBG_WARN("check cancel storage [%s][%s]", cancel_extract_item->path, start_path);
732                         if ((strncmp(cancel_extract_item->path, start_path, strlen(cancel_extract_item->path)) == 0)
733                                 && (cancel_extract_item->pid == -1 || cancel_extract_item->pid == pid)) {
734                                 MS_DBG_WARN("Receive cancel request [%s][%s]. STOP scan!!", cancel_extract_item->path, start_path);
735                                 unsigned int path_len = strlen(cancel_extract_item->path);
736
737                                 if (strlen(start_path) > path_len) {
738                                         if (start_path[path_len] == '/') {
739                                                 MS_DBG_ERR("start path is same as cancel path");
740                                                 ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
741                                         } else {
742                                                 MS_DBG_ERR("start path is not same as cancel path");
743                                         }
744                                 } else {
745                                         ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
746                                 }
747                         }
748                 }
749
750                 g_mutex_unlock(&extract_req_mutex);
751         }
752
753         if (scan_type == MS_MSG_STORAGE_ALL || scan_type == MS_MSG_STORAGE_PARTIAL) {
754                 if (g_directory_extract_processing == true) {
755                         MS_DBG_WARN("Now directory extract is start. So, storage extract is stopped.");
756                         __msc_pause_extract();
757                         MS_DBG_WARN("Now directory extract is end. So, storage extract is resumed.");
758                 }
759
760                 g_mutex_lock(&extract_blocked_mutex);
761                 /* check block path */
762                 if (g_extract_blocked_path != NULL) {
763                         //MS_DBG_WARN("check blocked storage [%s][%s]", g_extract_blocked_path, start_path);
764                         if (strncmp(start_path, g_extract_blocked_path, strlen(g_extract_blocked_path)) == 0) {
765                                 MS_DBG_ERR("Receive blocked message[%s][%s]. STOP extract!!", g_extract_blocked_path, start_path);
766                                 ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
767                         }
768                         if (is_end) {
769                                 MS_DBG("[END REQUEST]");
770                                 /*MS_SAFE_FREE(g_extract_blocked_path);*/
771                         } else {
772                                 MS_DBG("[NOT END REQUEST]");
773                         }
774                 }
775
776                 g_mutex_unlock(&extract_blocked_mutex);
777         }
778 END:
779         return ret;
780 }
781
782 static int __msc_set_storage_extract_status(ms_storage_scan_status_e status)
783 {
784         int res = MS_MEDIA_ERR_NONE;
785
786         stg_extract_status = status;
787
788         return res;
789 }
790
791 static int __msc_get_storage_extract_status(ms_storage_scan_status_e *status)
792 {
793         int res = MS_MEDIA_ERR_NONE;
794
795         *status = stg_extract_status;
796
797         return res;
798 }
799
800 static int __msc_resume_extract()
801 {
802         g_mutex_lock(&extract_data_mutex);
803
804         g_cond_signal(&extract_data_cond);
805
806         g_mutex_unlock(&extract_data_mutex);
807
808         return MS_MEDIA_ERR_NONE;
809 }
810
811 static int __msc_pause_extract()
812 {
813         g_mutex_lock(&extract_data_mutex);
814
815         while (g_directory_extract_processing)
816                 g_cond_wait(&extract_data_cond, &extract_data_mutex);
817
818         g_mutex_unlock(&extract_data_mutex);
819
820         return MS_MEDIA_ERR_NONE;
821 }
822
823 static int __msc_extract_set_db_status(ms_db_status_type_t status)
824 {
825         int res = MS_MEDIA_ERR_NONE;
826         //int err = 0;
827
828         if (!ms_config_set_int(VCONFKEY_PRIVATE_EXTRACTSTATUS, status)) {
829                 res = MS_MEDIA_ERR_VCONF_SET_FAIL;
830                 MS_DBG_ERR("ms_config_set_int failed");
831         }
832
833         return res;
834 }
835
836 int msc_get_remain_extract_request(ms_extract_type_e scan_type, int *remain_request)
837 {
838         int ret = MS_MEDIA_ERR_NONE;
839
840         switch (scan_type) {
841         case MS_EXTRACT_STORAGE:
842                 *remain_request = g_async_queue_length(storage_extract_queue);
843                 break;
844         case MS_EXTRACT_DIRECTORY:
845                 *remain_request = g_async_queue_length(folder_extract_queue);
846                 break;
847         default:
848                 MS_DBG_ERR("invalid parameter");
849                 ret = MS_MEDIA_ERR_INVALID_PARAMETER;
850                 break;
851         }
852
853         return ret;
854 }
855
856 int msc_get_dir_extract_status(bool *extract_status)
857 {
858         *extract_status = g_directory_extract_processing;
859
860         return MS_MEDIA_ERR_NONE;
861 }
862
863 int msc_stop_extract_thread(void)
864 {
865         ms_comm_msg_s *data = NULL;
866
867         if (storage_extract_queue) {
868                 /*notify to storage extract thread*/
869                 MS_MALLOC(data, sizeof(ms_comm_msg_s));
870                 if (data != NULL) {
871                         data->pid = POWEROFF;
872                         g_async_queue_push(storage_extract_queue, GINT_TO_POINTER(data));
873                 }
874         }
875
876         if (folder_extract_queue) {
877                 /*notify to folder extract thread*/
878                 MS_MALLOC(data, sizeof(ms_comm_msg_s));
879                 if (data != NULL) {
880                         data->pid = POWEROFF;
881                         g_async_queue_push(folder_extract_queue, GINT_TO_POINTER(data));
882                 }
883         }
884
885         return MS_MEDIA_ERR_NONE;
886 }
887
888 int msc_set_extract_cancel_path(const char *cancel_path)
889 {
890         if (g_extract_cancel_path != NULL) {
891                 MS_DBG_WARN("g_extract_cancel_path is not NULL");
892                 MS_SAFE_FREE(g_extract_cancel_path);
893         }
894
895         g_extract_cancel_path = strdup(cancel_path);
896
897         return MS_MEDIA_ERR_NONE;
898 }
899