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