[REFACTOR] encapsulate target struct (part 1)
[platform/core/system/swap-manager.git] / daemon / target.c
1 /*
2  *  DA manager
3  *
4  * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:
7  *
8  * Vyacheslav Cherkashin <v.cherkashin@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  * Contributors:
23  * - Samsung RnD Institute Russia
24  *
25  */
26
27
28 #define _GNU_SOURCE     /* for accept4() */
29 #include <sys/socket.h>
30
31 #include "target.h"
32
33 #include "daemon.h"     // for manager (it is need delete)
34 #include "smack.h"
35 #include "debug.h"
36
37
38 static struct target *target_malloc(void);
39 static void target_free(struct target *t);
40
41 struct target *target_ctor(void)
42 {
43         struct target *t;
44
45         t = target_malloc();
46         if (t) {
47                 t->pid = UNKNOWN_PID;
48                 t->socket = UNKNOWN_FD;
49                 t->event_fd = UNKNOWN_FD;
50                 t->recv_thread = 0;
51                 t->initial_log = 0;
52                 t->allocmem = 0;
53         }
54
55         return t;
56 }
57
58 void target_dtor(struct target *t)
59 {
60         t->recv_thread = -1;
61         t->allocmem = 0;
62         t->initial_log = 0;
63
64         if (t->event_fd != -1)
65                 close(t->event_fd);
66         t->event_fd = -1;
67
68         if (t->socket != UNKNOWN_FD)
69                 close(t->socket);
70         t->socket = -1;
71
72         target_free(t);
73 }
74
75
76 int target_accept(struct target *t, int sockfd)
77 {
78         int sock;
79
80         sock = accept4(sockfd, NULL, NULL, SOCK_CLOEXEC);
81         if (sock == UNKNOWN_FD)
82                 return 1;
83
84         /* accept succeed */
85         fd_setup_attributes(sock);
86
87         t->socket = sock;
88
89         return 0;
90 }
91
92 int target_send_msg(struct target *t, struct msg_target_t *msg)
93 {
94         return send_msg_to_sock(t->socket, msg);
95 }
96
97 int target_recv_msg(struct target *t, struct msg_target_t *msg)
98 {
99         return recv_msg_from_sock(t->socket, msg);
100 }
101
102
103 int target_start(struct target *t, void *(*start_routine) (void *))
104 {
105         return pthread_create(&t->recv_thread, NULL, start_routine, (void *)t);
106 }
107
108 int target_wait(struct target *t)
109 {
110         return pthread_join(t->recv_thread, NULL);
111 }
112
113
114 pid_t target_get_pid(struct target *t)
115 {
116         return t->pid;
117 }
118
119 void target_set_pid(struct target *t, pid_t pid)
120 {
121         t->pid = pid;
122 }
123
124 pid_t target_get_ppid(struct target *t)
125 {
126         return t->ppid;
127 }
128
129 void target_set_ppid(struct target *t, pid_t ppid)
130 {
131         t->ppid = ppid;
132 }
133
134 static int target_cnt = 0;
135 static pthread_mutex_t ts_mutex = PTHREAD_MUTEX_INITIALIZER;
136 static int target_use[MAX_TARGET_COUNT] = {0};
137 static struct target target_array[MAX_TARGET_COUNT];
138
139 static void target_array_lock(void)
140 {
141         pthread_mutex_lock(&ts_mutex);
142 }
143
144 static void target_array_unlock(void)
145 {
146         pthread_mutex_unlock(&ts_mutex);
147 }
148
149 static struct target *target_malloc(void)
150 {
151         int i;
152         struct target *t = NULL;
153
154         target_array_lock();
155         for (i = 0; i < MAX_TARGET_COUNT; i++) {
156                 if (target_use[i] == 0) {
157                         target_use[i] = 1;
158                         t = &target_array[i];
159                         break;
160                 }
161         }
162         target_array_unlock();
163
164         return t;
165 }
166
167 static void target_free(struct target *t)
168 {
169         target_array_lock();
170         target_use[t - target_array] = 0;
171         target_array_unlock();
172 }
173
174
175 void target_cnt_set(int cnt)
176 {
177         target_cnt = cnt;
178 }
179
180 int target_cnt_get(void)
181 {
182         return target_cnt;
183 }
184
185 int target_cnt_sub_and_fetch(void)
186 {
187         return __sync_sub_and_fetch(&target_cnt, 1);
188 }
189
190
191 struct target *target_get(int i)
192 {
193         return &target_array[i];
194 }
195
196
197
198
199
200 /*
201  * for all targets
202  */
203 int target_send_msg_to_all(struct msg_target_t *msg)
204 {
205         int i, ret = 0;
206         struct target *t;
207
208         target_array_lock();
209         for (i = 0; i < MAX_TARGET_COUNT; ++i) {
210                 if (target_use[i] == 0)
211                         continue;
212
213                 t = target_get(i);
214                 if (target_send_msg(t, msg))
215                         ret = 1;
216         }
217         target_array_unlock();
218
219         return ret;
220 }
221
222 void target_wait_all(void)
223 {
224         int i;
225         struct target *t;
226
227         target_array_lock();
228         for (i = 0; i < MAX_TARGET_COUNT; ++i) {
229                 if (target_use[i] == 0)
230                         continue;
231
232                 t = target_get(i);
233
234                 LOGI("join recv thread [%d] is started\n", i);
235                 target_wait(t);
236                 LOGI("join recv thread %d. done\n", i);
237         }
238         target_array_unlock();
239 }
240
241 uint64_t target_get_total_alloc(pid_t pid)
242 {
243         int i;
244         uint64_t ret = 0;
245         struct target *t;
246
247         target_array_lock();
248         for (i = 0; i < MAX_TARGET_COUNT; i++) {
249                 if (target_use[i] == 0)
250                         continue;
251
252                 t = target_get(i);
253                 if (target_get_pid(t) == pid) {
254                         ret = t->allocmem;
255                         goto unlock;
256                 }
257         }
258 unlock:
259         target_array_lock();
260
261         return ret;
262 }