Remove query_do_update_list()
[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 static GMutex extract_req_mutex;
48 static GMutex extract_blocked_mutex;
49 static char *g_extract_blocked_path;
50 bool g_directory_extract_processing;
51 static int stg_extract_status;
52
53 static GMutex extract_item_mutex;
54 static GMutex decode_mutex;
55
56 static s_extract_item* cancel_extract_item = NULL;
57 static s_extract_item* cur_extract_item = NULL;
58
59 static GCond extract_data_cond;
60 static GMutex extract_data_mutex;
61 #define VCONFKEY_PRIVATE_EXTRACTSTATUS "db/private/extractstatus"
62 #define LAST_EVENT 1
63 #define NORMAL_EVENT 0
64
65 static int __msc_check_extract_stop_status(int scan_type, const char *start_path, int pid, bool is_end);
66 static void __msc_set_storage_extract_status(ms_storage_scan_status_e status);
67 static void __msc_get_storage_extract_status(ms_storage_scan_status_e *status);
68 static void __msc_resume_extract(void);
69 static void __msc_pause_extract(void);
70 static int __msc_extract_set_db_status(ms_db_status_type_t status);
71 static void __msc_del_cancel_extract_item(void);
72 static void __msc_set_cur_extract_item(const char* cur_path, int pid);
73 static void __msc_del_cur_extract_item(void);
74 static void __msc_del_extract_blocked_path(const char* blocked_path);
75
76
77 typedef struct {
78         int media_type;
79         char *path;
80 } ms_item_info_s;
81
82 void msc_init_extract_thread(void)
83 {
84         if (!storage_extract_queue) storage_extract_queue = g_async_queue_new();
85         if (!folder_extract_queue) folder_extract_queue = g_async_queue_new();
86
87         g_mutex_init(&extract_req_mutex);
88         g_mutex_init(&extract_blocked_mutex);
89         g_mutex_init(&extract_data_mutex);
90
91         g_mutex_init(&extract_item_mutex);
92         g_mutex_init(&decode_mutex);
93
94         g_cond_init(&extract_data_cond);
95 }
96
97 void msc_deinit_extract_thread(void)
98 {
99         if (storage_extract_queue) g_async_queue_unref(storage_extract_queue);
100         if (folder_extract_queue) g_async_queue_unref(folder_extract_queue);
101
102         g_mutex_clear(&extract_req_mutex);
103         g_mutex_clear(&extract_blocked_mutex);
104         g_mutex_clear(&extract_data_mutex);
105
106         g_mutex_clear(&extract_item_mutex);
107         g_mutex_clear(&decode_mutex);
108
109         g_cond_clear(&extract_data_cond);
110 }
111
112 static int __msc_folder_bulk_extract(sqlite3 *handle, const char *storage_id, int storage_type, const char *path, int scan_type, int pid, uid_t uid, bool is_end)
113 {
114         MS_DBG_WARN("begin of __msc_folder_bulk_extract");
115         int ret = MS_MEDIA_ERR_NONE;
116         GArray *data_array = NULL;
117         ms_item_info_s* db_data = NULL;
118         int sleep_count = 0;
119
120         ret = ms_get_extract_list(handle, storage_id, storage_type, scan_type, path, is_end, uid, (void *)&data_array);
121         MS_DBG_RETVM_IF(ret != MS_MEDIA_ERR_NONE, MS_MEDIA_ERR_NONE, "ms_get_extract_list failed!!!");
122         MS_DBG_RETVM_IF(!data_array, MS_MEDIA_ERR_NONE, "data_array is NULL!!!");
123
124         while (data_array->len != 0) {
125                 db_data = NULL;
126
127                 ret = __msc_check_extract_stop_status(scan_type, path, pid, is_end);
128                 if (ret == MS_MEDIA_ERR_SCANNER_FORCE_STOP) {
129                         MS_DBG_ERR("__msc_folder_bulk_extract MS_MEDIA_ERR_SCANNER_FORCE_STOP");
130                         break;
131                 }
132
133                 db_data = g_array_index(data_array, ms_item_info_s*, 0);
134                 g_array_remove_index(data_array, 0);
135
136                 g_mutex_lock(&decode_mutex);
137                 ms_update_one_extract_item(handle, storage_id, storage_type, db_data);
138                 g_mutex_unlock(&decode_mutex);
139
140                 if (db_data) {
141                         g_free(db_data->path);
142                         g_free(db_data);
143                         db_data = NULL;
144                 }
145
146                 if (++sleep_count == 5) {
147                         sleep_count = 0;
148                         usleep(SCAN_SLEEP_TIME);
149                 }
150         }
151
152         while (data_array->len != 0) {
153                 db_data = g_array_index(data_array, ms_item_info_s *, 0);
154                 g_array_remove_index(data_array, 0);
155
156                 if (db_data) {
157                         g_free(db_data->path);
158                         g_free(db_data);
159                         db_data = NULL;
160                 }
161         }
162         g_array_free(data_array, FALSE);
163         data_array = NULL;
164
165         MS_DBG_WARN("end of __msc_folder_bulk_extract");
166         return ret;
167 }
168
169 gpointer msc_folder_extract_thread(gpointer data)
170 {
171         ms_comm_msg_s *extract_data = NULL;
172         int ret = MS_MEDIA_ERR_NONE;
173         sqlite3 *handle = NULL;
174         int scan_type;
175         ms_user_storage_type_e storage_type;
176         char *storage_id = NULL;
177         char *update_path = NULL;
178         uid_t uid = MEDIA_DEFAULT_UID;
179         int end_flag = NORMAL_EVENT;
180         ms_noti_type_e noti_type = MS_ITEM_INSERT;
181
182         while (1) {
183                 extract_data = g_async_queue_pop(folder_extract_queue);
184                 if (extract_data->pid == POWEROFF) {
185                         MS_DBG_ERR("power off");
186                         goto _POWEROFF;
187                 }
188
189                 MS_DBG_WARN("DIRECTORY EXTRACT START [%.*s %d]", MAX_MSG_SIZE, extract_data->msg, extract_data->msg_type);
190
191                 __msc_set_cur_extract_item(extract_data->msg, extract_data->pid);
192                 g_directory_extract_processing = true;
193                 uid = extract_data->uid;
194
195                 /*connect to media db, if conneting is failed, db updating is stopped*/
196                 ret = ms_connect_db(&handle, uid);
197                 if (ret != MS_MEDIA_ERR_NONE) {
198                         MS_DBG_ERR("ms_connect_db failed");
199                         goto NEXT;
200                 }
201
202                 scan_type = extract_data->msg_type;
203                 noti_type = extract_data->noti_type;
204
205                 storage_id = g_strdup(extract_data->storage_id);
206                 if (storage_id == NULL) {
207                         MS_DBG_ERR("storage_id NULL");
208                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
209                         goto NEXT;
210                 }
211
212                 MS_DBG("path : [%.*s], storage_id : [%s]", MAX_MSG_SIZE, extract_data->msg, storage_id);
213
214                 update_path = g_strdup(extract_data->msg);
215
216                 if (strlen(storage_id) == 0) {
217                         MS_DBG_ERR("storage_id length is 0. There is no information of your request [%.*s]", MAX_MSG_SIZE, extract_data->msg);
218                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
219                         goto NEXT;
220                 }
221
222                 if (scan_type != MS_MSG_DIRECTORY_SCANNING
223                         && scan_type != MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
224                         MS_DBG_ERR("Invalid request");
225                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
226                         goto NEXT;
227                 }
228                 end_flag = extract_data->result ? LAST_EVENT : NORMAL_EVENT;
229
230                 ret = ms_user_get_storage_type(uid, extract_data->msg, &storage_type);
231                 if (ret != MS_MEDIA_ERR_NONE) {
232                         MS_DBG_ERR("ms_user_get_storage_type failed");
233                         goto NEXT;
234                 }
235
236                 ret = __msc_check_extract_stop_status(extract_data->msg_type, update_path, extract_data->pid, end_flag);
237
238                 if (ret == MS_MEDIA_ERR_SCANNER_FORCE_STOP) {
239                         MS_DBG_ERR("MS_MEDIA_ERR_SCANNER_FORCE_STOP");
240                         goto NEXT;
241                 }
242
243                 /*insert data into media db */
244                 ret = msc_check_db_size(uid, extract_data->msg_type);
245                 if (ret != MS_MEDIA_ERR_NONE) {
246                         MS_DBG_ERR("NOT ENOUGH MEMORY");
247                         if (ret == MS_MEDIA_ERR_DB_FULL_FAIL)
248                                 ret = MS_MEDIA_ERR_NONE;
249
250                         goto NEXT;
251                 }
252
253                 ret = __msc_folder_bulk_extract(handle, extract_data->storage_id, storage_type, update_path, scan_type, extract_data->pid, uid, end_flag);
254
255 NEXT:
256                 g_directory_extract_processing = false;
257                 if (power_off2) {
258                         MS_DBG_ERR("power off");
259                         goto _POWEROFF;
260                 }
261
262                 /*Active flush */
263                 malloc_trim(0);
264
265                 if (extract_data->result) {
266                         MS_DBG_ERR("MS_MSG_SCANNER_COMPLETE");
267                         if (noti_type == MS_ITEM_INSERT || noti_type == MS_ITEM_UPDATE) {
268                                 /*send notification*/
269                                 char *folder_uuid = NULL;
270                                 ms_get_folder_id(handle, storage_id, extract_data->msg, &folder_uuid);
271                                 MS_DBG_WARN("storage_id = [%s], dir Path = [%s], folder_uuid = [%s], noti_type = [%d]", storage_id, update_path, folder_uuid, noti_type);
272                                 ms_send_dir_update_noti(update_path, folder_uuid, noti_type, extract_data->pid);
273                         }
274                         extract_data->msg_type = MS_MSG_EXTRACTOR_COMPLETE;
275                         msc_send_result(ret, extract_data);
276                 } else {
277                         MS_DBG_ERR("MS_MSG_SCANNER_PARTIAL");
278                         msc_send_result_partial(ret, MS_MSG_SCANNER_PARTIAL, extract_data->pid, extract_data->msg);
279                 }
280
281                 g_free(update_path);
282                 update_path = NULL;
283                 g_free(extract_data);
284                 extract_data = NULL;
285                 g_free(storage_id);
286                 storage_id = NULL;
287
288                 __msc_del_cur_extract_item();
289                 __msc_del_cancel_extract_item();
290
291                 MS_DBG_WARN("DIRECTORY EXTRACT END [%d]", ret);
292
293                 ms_storage_scan_status_e storage_scan_status = MS_STORAGE_SCAN_NONE;
294                 __msc_get_storage_extract_status(&storage_scan_status);
295
296                 /*get storage list and scan status from media db*/
297                 if (storage_scan_status != MS_STORAGE_SCAN_COMPLETE) {
298                         __msc_resume_extract();
299                         MS_DBG_WARN("extract RESUME OK");
300                 }
301
302                 /*disconnect form media db*/
303                 ms_disconnect_db(handle);
304                 usleep(SCAN_SLEEP_TIME);
305         }                       /*thread while*/
306
307 _POWEROFF:
308         __msc_resume_extract();
309
310         g_free(update_path);
311         g_free(extract_data);
312         g_free(storage_id);
313         ms_disconnect_db(handle);
314
315         return NULL;
316 }
317
318 gpointer msc_storage_extract_thread(gpointer data)
319 {
320         ms_comm_msg_s *extract_data = NULL;
321         int ret = MS_MEDIA_ERR_NONE;
322         sqlite3 *handle = NULL;
323         ms_user_storage_type_e storage_type = MS_USER_STORAGE_INTERNAL;
324         int scan_type;
325         char *update_path = NULL;
326         uid_t uid = MEDIA_DEFAULT_UID;
327         int end_flag = NORMAL_EVENT;
328         int tem_ret = MS_MEDIA_ERR_NONE;
329
330         while (1) {
331                 __msc_set_storage_extract_status(MS_STORAGE_SCAN_DONE);
332                 extract_data = g_async_queue_pop(storage_extract_queue);
333                 if (extract_data->pid == POWEROFF) {
334                         MS_DBG_ERR("power off");
335                         goto _POWEROFF;
336                 }
337
338                 __msc_set_storage_extract_status(MS_STORAGE_SCAN_META_PROCESSING);
339
340                 MS_DBG_WARN("STORAGE extract START extract len is %d ", g_async_queue_length(storage_extract_queue));
341
342                 scan_type = extract_data->msg_type;
343                 if (scan_type != MS_MSG_STORAGE_ALL
344                         && scan_type != MS_MSG_STORAGE_PARTIAL) {
345                         MS_DBG_ERR("Invalid request[%d]", scan_type);
346                         msc_remove_extract_request(extract_data);
347                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
348                         goto NEXT;
349                 }
350
351                 uid = extract_data->uid;
352
353                 /*connect to media db, if conneting is failed, db updating is stopped*/
354                 ret = ms_connect_db(&handle, uid);
355                 if (ret != MS_MEDIA_ERR_NONE) {
356                         MS_DBG_ERR("ms_connect_db falied!");
357                         continue;
358                 }
359
360                 end_flag = extract_data->result ? LAST_EVENT : NORMAL_EVENT;
361                 update_path = g_strdup(extract_data->msg);
362                 if (!MS_STRING_VALID(update_path)) {
363                         MS_DBG_ERR("Invalid update_path");
364                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
365                         goto NEXT;
366                 }
367                 MS_DBG_WARN("extract storage_id is [%s], path [%s]", extract_data->storage_id, update_path);
368                 ret = ms_user_get_storage_type(uid, extract_data->msg, &storage_type);
369                 if (ret != MS_MEDIA_ERR_NONE) {
370                         MS_DBG_ERR("ms_user_get_storage_type failed");
371                         goto NEXT;
372                 }
373                 if (storage_type == MS_USER_STORAGE_EXTERNAL_USB) {
374                         if (!ms_storage_mount_status(update_path)) {
375                                 MS_DBG_ERR("%s is unmounted", update_path);
376                                 ret = MS_MEDIA_ERR_USB_UNMOUNTED;
377                                 msc_remove_extract_request(extract_data);
378                                 goto NEXT;
379                         }
380                 }
381                 ms_set_storage_scan_status(handle, extract_data->storage_id, MEDIA_EXTRACT_PROCESSING, uid);
382                 __msc_extract_set_db_status(MS_DB_UPDATING);
383
384                 ret = msc_check_db_size(uid, extract_data->msg_type);
385                 if (ret != MS_MEDIA_ERR_NONE) {
386                         MS_DBG_ERR("NOT ENOUGH MEMORY");
387                         __msc_extract_set_db_status(MS_DB_STOPPED);
388                         goto NEXT;
389                 }
390
391                 /*extract meta*/
392                 ret = __msc_folder_bulk_extract(handle, extract_data->storage_id, storage_type, update_path, scan_type, extract_data->pid, uid, end_flag);
393                 MS_DBG_WARN("extract PAUSE");
394                 __msc_pause_extract();
395                 MS_DBG_WARN("extract RESUME");
396
397                 tem_ret = __msc_check_extract_stop_status(extract_data->msg_type, update_path, extract_data->pid, end_flag);
398                 if (tem_ret == MS_MEDIA_ERR_SCANNER_FORCE_STOP) {
399                         ms_set_storage_scan_status(handle, extract_data->storage_id, MEDIA_EXTRACT_STOP, uid);
400                         __msc_set_storage_extract_status(MS_STORAGE_SCAN_META_STOP);
401                         MS_DBG_WARN("storage scan force stopped");
402                         /* set vconf key db extract status */
403                         __msc_extract_set_db_status(MS_DB_STOPPED);
404
405                         msc_remove_extract_request(extract_data);
406                         goto NEXT;
407                 }
408
409                 if (extract_data->result) {
410                         MS_DBG_WARN("extract_data->result is true, MS_STORAGE_SCAN_COMPLETE");
411                         __msc_del_extract_blocked_path(update_path);
412                         ms_set_storage_scan_status(handle, extract_data->storage_id, MEDIA_EXTRACT_COMPLETE, uid);
413                         __msc_set_storage_extract_status(MS_STORAGE_SCAN_COMPLETE);
414
415                         /* send notification */
416                         ms_send_dir_update_noti(update_path, NULL, MS_ITEM_UPDATE, extract_data->pid);
417                         /* set vconf key db extract status */
418                         __msc_extract_set_db_status(MS_DB_UPDATED);
419                 }
420 NEXT:
421                 g_free(update_path);
422                 update_path = NULL;
423
424                 if (power_off2) {
425                         MS_DBG_ERR("power off");
426                         goto _POWEROFF;
427                 }
428
429                 /*disconnect form media db*/
430                 ms_disconnect_db(handle);
431
432                 /*Active flush */
433                 malloc_trim(0);
434
435                 if (extract_data->result) {
436                         extract_data->msg_type = MS_MSG_EXTRACTOR_COMPLETE;
437                         msc_send_result(ret, extract_data);
438                 }
439
440                 g_free(extract_data);
441                 extract_data = NULL;
442
443                 MS_DBG_WARN("STORAGE EXTRACT END[%d]", ret);
444                 usleep(SCAN_SLEEP_TIME);
445         }                       /*thread while*/
446
447 _POWEROFF:
448         MS_SAFE_FREE(extract_data);
449         ms_disconnect_db(handle);
450
451         return NULL;
452 }
453
454 void msc_insert_exactor_request(int message_type, bool ins_status, const char *storage_id, const char *path, int pid, uid_t uid, ms_noti_type_e noti_type)
455 {
456         ms_comm_msg_s *extract_data = g_new0(ms_comm_msg_s, 1);
457
458         extract_data->msg_type = message_type;
459         extract_data->pid = pid;
460         extract_data->uid = uid;
461         extract_data->result = ins_status;
462         extract_data->noti_type = noti_type;
463         SAFE_STRLCPY(extract_data->msg, path, sizeof(extract_data->msg));
464         SAFE_STRLCPY(extract_data->storage_id, storage_id, sizeof(extract_data->storage_id));
465
466         if (message_type == MS_MSG_STORAGE_ALL || message_type == MS_MSG_STORAGE_PARTIAL || message_type == MS_MSG_STORAGE_INVALID) {
467                 g_async_queue_push(storage_extract_queue, extract_data);
468                 MS_DBG("insert to storage exactor queue. msg_type [%d]", ins_status);
469         } else if (message_type == MS_MSG_DIRECTORY_SCANNING || message_type == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
470                 g_async_queue_push(folder_extract_queue, extract_data);
471                 MS_DBG("insert to dir exactor queue. msg_type [%d]", ins_status);
472         } else {
473                 MS_DBG_ERR("try to insert to exactor scan with msg_type [%d]", message_type);
474                 g_free(extract_data);
475         }
476 }
477
478 int msc_remove_extract_request(const ms_comm_msg_s *recv_msg)
479 {
480         int i = 0;
481         int j = 0;
482
483         if (recv_msg == NULL) {
484                 MS_DBG_ERR("recv_msg is null");
485                 return MS_MEDIA_ERR_INVALID_PARAMETER;
486         }
487         const char *storageid = recv_msg->storage_id;
488         int len = g_async_queue_length(storage_extract_queue);
489         ms_comm_msg_s *msg = NULL;
490         GAsyncQueue *temp_queue = NULL;
491
492         MS_DBG_WARN("exactor_req_mutex is LOCKED");
493         g_mutex_lock(&extract_req_mutex);
494
495         if (len <= 0) {
496                 MS_DBG_ERR("Request is not stacked");
497                 goto END_REMOVE_REQUEST;
498         }
499
500         temp_queue = g_async_queue_new();
501
502         for (i = 0; i < len; i++) {
503                 /*create new queue to compare request*/
504                 msg = g_async_queue_pop(storage_extract_queue);
505                 if ((strcmp(msg->storage_id, storageid) == 0)) {
506                         if (msg->result) {
507                                 MS_DBG_WARN("force stop storage scan");
508                                 msg->msg_type = MS_MSG_EXTRACTOR_COMPLETE;
509                                 msc_send_result(MS_MEDIA_ERR_SCANNER_FORCE_STOP, msg);
510                         }
511                         g_free(msg);
512                 } else {
513                         g_async_queue_push(temp_queue, msg);
514                 }
515         }
516         len = g_async_queue_length(temp_queue);
517
518         for (j = 0; j < len; j++) {
519                 msg = g_async_queue_pop(temp_queue);
520                 if (msg)
521                         g_async_queue_push(storage_extract_queue, msg);
522         }
523         g_async_queue_unref(temp_queue);
524
525 END_REMOVE_REQUEST:
526         g_mutex_unlock(&extract_req_mutex);
527         MS_DBG_WARN("exactor_req_mutex is UNLOCKED");
528         __msc_del_extract_blocked_path(recv_msg->msg);
529
530         return MS_MEDIA_ERR_NONE;
531 }
532
533 static int __msc_set_extract_item(s_extract_item** item, const char* path, int pid)
534 {
535         s_extract_item* extract_item = *item;
536
537
538         if (!extract_item)
539                 extract_item = g_new0(s_extract_item, 1);
540
541         g_free(extract_item->path);
542
543         extract_item->path = g_strdup(path);
544         extract_item->pid = pid;
545
546         *item = extract_item;
547
548         MS_DBG_SWARN("__msc_set_extract_item path[%s],pid[%d]", extract_item->path, extract_item->pid);
549
550         return MS_MEDIA_ERR_NONE;
551 }
552
553 static void __msc_del_extract_item(s_extract_item** item)
554 {
555         if (*item != NULL) {
556                 g_free((*item)->path);
557                 g_free(*item);
558                 *item = NULL;
559         }
560 }
561
562 int msc_set_cancel_extract_item(const char* cancel_path, int pid)
563 {
564         int ret = -1;
565         MS_DBG_WARN("msc_set_cancel_extract_item begin");
566         g_mutex_lock(&extract_item_mutex);
567         if (cancel_path == NULL) {
568                 MS_DBG_ERR("cancel_path invalid...");
569                 return ret;
570         }
571
572         if (cur_extract_item && cur_extract_item->path) {
573                 if ((strcmp(cur_extract_item->path, cancel_path) == 0) && (pid == cur_extract_item->pid))
574                         ret = __msc_set_extract_item(&cancel_extract_item, cancel_path, pid);
575                 else if ((pid == -1) && (strncmp(cur_extract_item->path, cancel_path, strlen(cancel_path)) == 0))
576                         ret = __msc_set_extract_item(&cancel_extract_item, cancel_path, pid);
577         }
578         g_mutex_unlock(&extract_item_mutex);
579
580         MS_DBG_WARN("msc_set_cancel_extract_item end");
581         return ret;
582 }
583
584 static void __msc_del_cancel_extract_item(void)
585 {
586         g_mutex_lock(&extract_item_mutex);
587         __msc_del_extract_item(&cancel_extract_item);
588         g_mutex_unlock(&extract_item_mutex);
589 }
590
591 static void __msc_set_cur_extract_item(const char* cur_path, int pid)
592 {
593         g_mutex_lock(&extract_item_mutex);
594         __msc_set_extract_item(&cur_extract_item, cur_path, pid);
595         g_mutex_unlock(&extract_item_mutex);
596 }
597
598 static void __msc_del_cur_extract_item(void)
599 {
600         g_mutex_lock(&extract_item_mutex);
601         __msc_del_extract_item(&cur_extract_item);
602         g_mutex_unlock(&extract_item_mutex);
603 }
604
605 void msc_set_extract_blocked_path(const char *blocked_path)
606 {
607         MS_DBG_FENTER();
608
609         g_mutex_lock(&extract_blocked_mutex);
610
611         if (g_extract_blocked_path != NULL) {
612                 MS_DBG_SERR("g_extract_blocked_path is not NULL [%s]", g_extract_blocked_path);
613                 g_free(g_extract_blocked_path);
614         }
615
616         g_extract_blocked_path = g_strdup(blocked_path);
617         MS_DBG_ERR("g_extract_blocked_path is set [%s]", g_extract_blocked_path);
618         g_mutex_unlock(&extract_blocked_mutex);
619
620         MS_DBG_FLEAVE();
621 }
622
623 static void __msc_del_extract_blocked_path(const char* blocked_path)
624 {
625         MS_DBG_FENTER();
626
627         g_mutex_lock(&extract_blocked_mutex);
628
629         if (blocked_path) {
630                 if (g_extract_blocked_path && (0 == strncmp(blocked_path, g_extract_blocked_path, strlen(g_extract_blocked_path)))) {
631                         MS_DBG_ERR("g_extract_blocked_path is deleted  [%s]", g_extract_blocked_path);
632                         MS_SAFE_FREE(g_extract_blocked_path);
633                 }
634         } else {
635                 if (g_extract_blocked_path != NULL) {
636                         MS_DBG_SERR("g_extract_blocked_path is deleted [%s]", g_extract_blocked_path);
637                         MS_SAFE_FREE(g_extract_blocked_path);
638                 }
639         }
640
641         g_mutex_unlock(&extract_blocked_mutex);
642
643         MS_DBG_FLEAVE();
644 }
645
646 static int __msc_check_extract_stop_status(int scan_type, const char *start_path, int pid, bool is_end)
647 {
648         int ret = MS_MEDIA_ERR_NONE;
649
650         /*check poweroff status*/
651         if (power_off2) {
652                 MS_DBG_ERR("Power off");
653                 ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
654                 goto END;
655         }
656
657         if (scan_type == MS_MSG_DIRECTORY_SCANNING || scan_type == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
658                 g_mutex_lock(&extract_req_mutex);
659                 /* check cancel path */
660                 //MS_DBG_ERR("__msc_check_extract_stop_status...");
661                 if ((cancel_extract_item != NULL) && (cancel_extract_item->path != NULL)) {
662                         MS_DBG_SWARN("check cancel storage [%s][%s]", cancel_extract_item->path, start_path);
663                         if ((strncmp(cancel_extract_item->path, start_path, strlen(cancel_extract_item->path)) == 0)
664                                 && (cancel_extract_item->pid == -1 || cancel_extract_item->pid == pid)) {
665                                 MS_DBG_SWARN("Receive cancel request [%s][%s]. STOP scan!!", cancel_extract_item->path, start_path);
666                                 unsigned int path_len = strlen(cancel_extract_item->path);
667
668                                 if (strlen(start_path) > path_len) {
669                                         if (start_path[path_len] == '/') {
670                                                 MS_DBG_ERR("start path is same as cancel path");
671                                                 ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
672                                         } else {
673                                                 MS_DBG_ERR("start path is not same as cancel path");
674                                         }
675                                 } else {
676                                         ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
677                                 }
678                         }
679                 }
680
681                 g_mutex_unlock(&extract_req_mutex);
682         }
683
684         if (scan_type == MS_MSG_STORAGE_ALL || scan_type == MS_MSG_STORAGE_PARTIAL) {
685                 if (g_directory_extract_processing == true) {
686                         MS_DBG_WARN("Now directory extract is start. So, storage extract is stopped.");
687                         __msc_pause_extract();
688                         MS_DBG_WARN("Now directory extract is end. So, storage extract is resumed.");
689                 }
690
691                 g_mutex_lock(&extract_blocked_mutex);
692                 /* check block path */
693                 if (g_extract_blocked_path != NULL) {
694                         //MS_DBG_SWARN("check blocked storage [%s][%s]", g_extract_blocked_path, start_path);
695                         if (strncmp(start_path, g_extract_blocked_path, strlen(g_extract_blocked_path)) == 0) {
696                                 MS_DBG_SERR("Receive blocked message[%s][%s]. STOP extract!!", g_extract_blocked_path, start_path);
697                                 ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
698                         }
699                         if (is_end) {
700                                 MS_DBG("[END REQUEST]");
701                                 /*MS_SAFE_FREE(g_extract_blocked_path);*/
702                         } else {
703                                 MS_DBG("[NOT END REQUEST]");
704                         }
705                 }
706
707                 g_mutex_unlock(&extract_blocked_mutex);
708         }
709 END:
710         return ret;
711 }
712
713 static void __msc_set_storage_extract_status(ms_storage_scan_status_e status)
714 {
715         stg_extract_status = status;
716 }
717
718 static void __msc_get_storage_extract_status(ms_storage_scan_status_e *status)
719 {
720         *status = stg_extract_status;
721 }
722
723 static void __msc_resume_extract(void)
724 {
725         g_mutex_lock(&extract_data_mutex);
726
727         g_cond_signal(&extract_data_cond);
728
729         g_mutex_unlock(&extract_data_mutex);
730 }
731
732 static void __msc_pause_extract(void)
733 {
734         g_mutex_lock(&extract_data_mutex);
735
736         while (g_directory_extract_processing)
737                 g_cond_wait(&extract_data_cond, &extract_data_mutex);
738
739         g_mutex_unlock(&extract_data_mutex);
740 }
741
742 static int __msc_extract_set_db_status(ms_db_status_type_t status)
743 {
744         int res = MS_MEDIA_ERR_NONE;
745         //int err = 0;
746
747         if (!ms_config_set_int(VCONFKEY_PRIVATE_EXTRACTSTATUS, status)) {
748                 res = MS_MEDIA_ERR_INTERNAL;
749                 MS_DBG_ERR("ms_config_set_int failed");
750         }
751
752         return res;
753 }
754