[COPYRIGHT] copyright update
[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(void *arg)
43 {
44         (void)arg;
45         int fd_pipe[2];
46         ssize_t nrd, nwr;
47
48         LOGI("transfer thread started\n");
49
50         pipe(fd_pipe);
51         while (1) {
52                 nrd = splice(manager.buf_fd, NULL,
53                              fd_pipe[1], NULL,
54                              BUF_SIZE, 0);
55                 if (nrd == -1) {
56                         if (errno == EAGAIN) {
57                                 LOGI("No more data to read\n");
58                                 break;
59                         }
60                         LOGE("Cannot splice read: %s\n", strerror(errno));
61                         return NULL;
62                 }
63
64                 nwr = splice(fd_pipe[0], NULL,
65                              manager.host.data_socket, NULL,
66                              nrd, 0);
67                 if (nwr == -1) {
68                         LOGE("Cannot splice write: %s\n", strerror(errno));
69                         return NULL;
70                 }
71                 if (nwr != nrd) {
72                         LOGW("nrd - nwr = %d\n", nrd - nwr);
73                 }
74         }
75         close(fd_pipe[0]);
76         close(fd_pipe[1]);
77
78         LOGI("transfer thread finished\n");
79
80         return NULL;
81 }
82
83 int start_transfer()
84 {
85         int saved_flags;
86
87         if (manager.host.data_socket == -1) {
88                 LOGW("won't start transfer thread: data socket isn't open\n");
89                 return 0;
90         }
91
92         if (manager.transfer_thread != -1) { // already started
93                 LOGW("transfer already running\n");
94                 stop_transfer();
95         }
96
97         saved_flags = fcntl(manager.buf_fd, F_GETFL);
98         fcntl(manager.buf_fd, F_SETFL, saved_flags & ~O_NONBLOCK);
99
100         if(pthread_create(&(manager.transfer_thread),
101                           NULL,
102                           transfer_thread,
103                           NULL) < 0)
104         {
105                 LOGE("Failed to create transfer thread\n");
106                 return -1;
107         }
108
109         return 0;
110 }
111
112 void stop_transfer()
113 {
114         int saved_flags;
115
116         if (manager.transfer_thread == -1) {
117                 LOGI("transfer thread not running\n");
118                 return;
119         }
120         LOGI("stopping transfer\n");
121
122         flush_buf();
123         saved_flags = fcntl(manager.buf_fd, F_GETFL);
124         fcntl(manager.buf_fd, F_SETFL, saved_flags | O_NONBLOCK);
125         pthread_join(manager.transfer_thread, NULL);
126         manager.transfer_thread = -1;
127
128         LOGI("transfer thread joined\n");
129 }