[FIX] empty string in sprintf
[platform/core/system/swap-manager.git] / daemon / transfer_thread.c
1 /*
2  *  DA manager
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:
7  *
8  * Cherepanov Vitaliy <v.cherepanov@samsung.com>
9  * Nikita Kalyazin    <n.kalyazin@samsung.com>
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  * http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  *
23  * Contributors:
24  * - Samsung RnD Institute Russia
25  *
26  */
27
28
29 #define _GNU_SOURCE
30 #include <fcntl.h>
31 #include <unistd.h>
32 #include <errno.h>
33 #include <string.h>
34
35 #include "daemon.h"
36 #include "buffer.h"
37 #include "debug.h"
38 #include "transfer_thread.h"
39
40 #define BUF_SIZE 4096
41
42 static void transfer_thread_cleanup(void *arg)
43 {
44         int *fd_pipe;
45         fd_pipe = (int *) arg;
46
47         close(fd_pipe[0]);
48         close(fd_pipe[1]);
49
50 }
51
52 static void *transfer_thread(void *arg)
53 {
54         (void)arg;
55         int fd_pipe[2];
56         ssize_t nrd, nwr;
57
58         //init thread
59         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
60
61         //init pipe
62         pipe(fd_pipe);
63         //set cleanup function
64         pthread_cleanup_push(transfer_thread_cleanup, (void *)fd_pipe);
65
66         pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
67
68         LOGI("transfer thread started\n");
69
70         while (1) {
71                 nrd = splice(manager.buf_fd, NULL,
72                              fd_pipe[1], NULL,
73                              BUF_SIZE, 0);
74                 if (nrd == -1) {
75                         if (errno == EAGAIN) {
76                                 LOGI("No more data to read\n");
77                                 break;
78                         }
79                         LOGE("Cannot splice read: %s\n", strerror(errno));
80                         goto thread_exit;
81                 }
82
83                 nwr = splice(fd_pipe[0], NULL,
84                              manager.host.data_socket, NULL,
85                              nrd, 0);
86
87                 if (nwr == -1) {
88                         LOGE("Cannot splice write: %s\n", strerror(errno));
89                         goto thread_exit;
90                 }
91                 if (nwr != nrd) {
92                         LOGW("nrd - nwr = %d\n", nrd - nwr);
93                 }
94         }
95
96         thread_exit:
97         pthread_cleanup_pop(1);
98
99         LOGI("transfer thread finished. return\n");
100
101         return NULL;
102 }
103
104 int start_transfer(void)
105 {
106         int saved_flags;
107
108         if (manager.host.data_socket == -1) {
109                 LOGW("won't start transfer thread: data socket isn't open\n");
110                 return 0;
111         }
112
113         if (manager.transfer_thread != -1) { // already started
114                 LOGW("transfer already running\n");
115                 stop_transfer();
116         }
117
118         saved_flags = fcntl(manager.buf_fd, F_GETFL);
119         fcntl(manager.buf_fd, F_SETFL, saved_flags & ~O_NONBLOCK);
120
121         if(pthread_create(&(manager.transfer_thread),
122                           NULL,
123                           transfer_thread,
124                           NULL) < 0)
125         {
126                 LOGE("Failed to create transfer thread\n");
127                 return -1;
128         }
129
130         return 0;
131 }
132
133 void stop_transfer(void)
134 {
135         int saved_flags;
136         int ret = 0;
137
138         if (manager.transfer_thread == -1) {
139                 LOGI("transfer thread not running\n");
140                 return;
141         }
142         LOGI("stopping transfer\n");
143
144         flush_buf();
145         saved_flags = fcntl(manager.buf_fd, F_GETFL);
146         fcntl(manager.buf_fd, F_SETFL, saved_flags | O_NONBLOCK);
147         wake_up_buf();
148
149         LOGI("joining thread...\n");
150         ret = pthread_join(manager.transfer_thread, NULL);
151         if (ret != 0)
152                 LOGW("pthread_join: unknown error %d\n", ret);
153
154         manager.transfer_thread = -1;
155
156         LOGI("transfer thread stoped\n");
157 }