2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
27 #include <sys/syscall.h>
29 #include "mf-delete.h"
30 #include "mf-delete-internal.h"
31 #include "mf-cancel.h"
32 #include "mf-fo-common.h"
33 #include "mf-fo-internal.h"
34 #include "mf-fo-debug.h"
35 #include "mf-callback.h"
38 extern pthread_mutex_t gLockMsg;
39 extern pthread_cond_t gCondMsg;
41 struct _mf_del_handle {
55 static double get_time(void)
59 gettimeofday(&timev, NULL);
60 return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
63 static void __mf_delete_free_handle(struct _mf_del_handle *handle)
68 g_mutex_free(handle->lock);
71 g_cond_free(handle->cond);
73 if (handle->src_items) {
74 g_list_foreach(handle->src_items, (GFunc)free, NULL);
75 g_list_free(handle->src_items);
77 if (handle->msg.current_real) {
78 g_free(handle->msg.current_real);
79 handle->msg.current_real = NULL;
87 static gboolean _del_msg_publish(gpointer data)
89 struct _mf_del_handle *handle = NULL;
90 handle = (struct _mf_del_handle *)data;
96 MYFILE_MAGIC_SET(&msg, MYFILE_MAGIC_PIPE_DATA);
98 g_mutex_lock(handle->lock);
99 msg.msg_type = handle->msg.msg_type;
100 msg.error_code = handle->msg.error_code;
101 msg.current = handle->msg.current;
102 msg.current_index = handle->msg.current_index;
103 msg.total_index = handle->msg.total_index;
104 msg.current_size = handle->msg.current_size;
105 msg.total_size = handle->msg.total_size;
106 msg.current_real = handle->msg.current_real;
107 msg.pipe = handle->pipe;
108 g_mutex_unlock(handle->lock);
111 ecore_pipe_write(handle->pipe, &msg, sizeof(msg));
117 static void _del_msg_cb(mf_msg_type msg_type, const char *real, unsigned long long size, int error_code, void *data)
119 struct _mf_del_handle *handle = NULL;
120 handle = (struct _mf_del_handle *)data;
122 pthread_mutex_lock(&gLockMsg);
123 while (flagMsg == 0) {
124 mf_fo_loge("!!!!!!!!!!!! wait");
125 pthread_cond_wait(&gCondMsg, &gLockMsg);
128 pthread_mutex_unlock(&gLockMsg);
131 g_mutex_lock(handle->lock);
132 handle->msg.msg_type = msg_type;
133 if (msg_type == MF_MSG_ERROR) {
134 handle->msg.error_code = error_code;
136 if (handle->msg.current_real) {
137 free(handle->msg.current_real);
139 handle->msg.current_real = strdup(real);
142 handle->msg.error_code = 0;
143 if (msg_type == MF_MSG_DOING) {
145 if (handle->msg.current_real) {
146 free(handle->msg.current_real);
148 handle->msg.current_real = strdup(real);
150 handle->msg.current_size += size;
151 handle->msg.error_code = 0;
152 } else if (msg_type == MF_MSG_SKIP) {
153 handle->msg.total_size -= size;
154 handle->msg.error_code = 0;
157 g_mutex_unlock(handle->lock);
159 _del_msg_publish(handle);
165 static void *delete_thread(void *data)
167 struct _mf_del_handle *handle = NULL;
168 handle = (struct _mf_del_handle *)data;
170 _mf_fo_msg_cb msg_cb = NULL;
171 gboolean cancelled = FALSE;
172 double s_start = 0.0;
174 double c_start = 0.0;
176 char err_buf[MF_ERR_BUF] = { 0, };
179 GList *tmp_src_list = NULL;
180 unsigned long long t_size = 0;
182 msg_cb = _del_msg_cb;
184 s_start = get_time();
185 tmp_src_list = handle->src_items;
186 while (tmp_src_list) {
187 if (tmp_src_list->data) {
188 const char *s_path = NULL;
189 unsigned long long size = 0;
191 s_path = tmp_src_list->data;
192 if (access(s_path, R_OK) == 0) {
193 int err = _mf_fo_get_total_item_size(s_path, &size);
195 mf_fo_loge("Fail to get size of %s", s_path);
196 /*handle->src_items = g_list_remove(handle->src_items, s_path);*/
198 _del_msg_cb(MF_MSG_ERROR, s_path, 0, (MF_FO_ERR_SRC_CLASS | _mf_fo_errno_to_mferr(-err)), handle);
200 goto ERROR_END_THREAD;
202 mf_fo_logi("size of %s - %lld", s_path, size);
206 MF_FILE_ERROR_LOG(err_buf, "Unable to access ", s_path);
207 /*handle->src_items = g_list_remove(handle->src_items, s_path);*/
209 _del_msg_cb(MF_MSG_ERROR, s_path, 0, (MF_FO_ERR_SRC_CLASS | _mf_fo_errno_to_mferr(errno)), handle);
211 goto ERROR_END_THREAD;
214 tmp_src_list = g_list_next(tmp_src_list);
217 g_mutex_lock(handle->lock);
218 handle->msg.total_size = t_size;
219 g_mutex_unlock(handle->lock);
222 c_start = get_time();
223 tmp_src_list = handle->src_items;
224 while (tmp_src_list) {
225 if (tmp_src_list->data) {
226 const char *s_path = NULL;
227 s_path = tmp_src_list->data;
229 g_mutex_lock(handle->lock);
230 handle->msg.current_index++;
231 handle->msg.current = s_path;
232 g_mutex_unlock(handle->lock);
233 ret = _mf_delete_del_internal(s_path, handle->cancel, msg_cb, handle);
236 if (handle->cancel) {
237 mf_cancel_set_cancelled(handle->cancel);
243 mf_fo_loge("Fail to delete [%s]", s_path);
246 tmp_src_list = g_list_next(tmp_src_list);
249 mf_fo_logi("## Total src size - %lld byte, size time : %lf sec, delete time : %lf sec",
250 handle->msg.total_size, s_stop - s_start, c_stop - c_start);
254 _del_msg_cb(MF_MSG_CANCELLED, NULL, 0, 0, handle);
261 _del_msg_cb(MF_MSG_SYNC, NULL, 0, 0, handle);
265 mf_fo_logi("sync time : %lf sec", stop - start);
268 _del_msg_cb(MF_MSG_END, NULL, 0, 0, handle);
270 __mf_delete_free_handle(handle);
273 mf_fo_loga("handle is NULL");
277 mf_fo_logd("The end of del_thread");
281 int mf_delete_items(GList *item_list, mf_cancel *cancel, gboolean sync, void *u_data)
283 struct _mf_del_handle *handle = NULL;
284 GList *tmp_list = NULL;
288 mf_fo_loge("item_list is NULL");
289 return -(MF_FO_ERR_ARGUMENT);
292 if (!g_thread_supported()) {
296 handle = malloc(sizeof(struct _mf_del_handle));
298 mf_fo_loge("Fail to allocate handle");
299 return -(MF_FO_ERR_MEM);
301 memset(handle, 0x00, sizeof(struct _mf_del_handle));
303 handle->lock = g_mutex_new();
305 mf_fo_loge("Fail to allocate mutex");
309 handle->cond = g_cond_new();
311 mf_fo_loge("Fail to allocate cond");
316 handle->cancel = cancel;
317 handle->u_data = u_data;
319 pthread_mutex_lock(&gLockMsg);
321 pthread_mutex_unlock(&gLockMsg);
323 tmp_list = item_list;
325 if (tmp_list->data) {
326 char *src_item = NULL;
327 src_item = strdup((char *)tmp_list->data);
329 if (_mf_fo_check_exist(src_item)) {
330 handle->src_items = g_list_append(handle->src_items, src_item);
332 mf_fo_loge("src_item[%s] is not existed", src_item);
333 err = MF_FO_ERR_ARGUMENT;
338 mf_fo_loge("Fail to allocate memory");
343 tmp_list = g_list_next(tmp_list);
346 if (!handle->src_items) {
347 mf_fo_loge("Fail to create src list");
348 err = MF_FO_ERR_ARGUMENT;
352 handle->pipe = ecore_pipe_add(mf_callback_thread_pipe_cb, u_data);
354 if (!g_thread_create((GThreadFunc) delete_thread, handle, FALSE, NULL)) {
355 mf_fo_loge("Fail to create delete thread");
363 __mf_delete_free_handle(handle);