sensord: fix the bug/memory leak/inefficient code
[platform/core/system/sensord.git] / src / server / server.cpp
1 /*
2  * sensord
3  *
4  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <systemd/sd-daemon.h>
21 #include <server.h>
22 #include <sensor_loader.h>
23 #include <command_common.h>
24 #include <command_worker.h>
25 #include <thread>
26 #include <sys/epoll.h>
27 #include <sensor_event_poller.h>
28
29 #define SYSTEMD_SOCKET_MAX    2
30
31 using std::thread;
32
33 server::server()
34 : m_mainloop(NULL)
35 {
36
37 }
38
39 server::~server()
40 {
41         stop();
42 }
43
44 int server::get_systemd_socket(const char *name)
45 {
46         int type = SOCK_STREAM;
47         int listening = 1;
48         size_t length = 0;
49         int fd = -1;
50         int fd_env = 1;
51         int fd_index;
52
53         if (!strcmp(name, EVENT_CHANNEL_PATH)) {
54                 type = SOCK_SEQPACKET;
55                 listening = -1;
56                 fd_env = 0;
57         }
58
59         if (sd_listen_fds(fd_env) < 0) {
60                 _E("Failed to listen fds from systemd");
61                 return -1;
62         }
63
64         for (fd_index = 0; fd_index < SYSTEMD_SOCKET_MAX; ++fd_index) {
65                 fd = SD_LISTEN_FDS_START + fd_index;
66
67                 if (sd_is_socket_unix(fd, type, listening, name, length) > 0)
68                         return fd;
69         }
70
71         return -1;
72 }
73
74 void server::accept_command_channel(void)
75 {
76         command_worker *cmd_worker;
77         _I("Command channel acceptor is started");
78
79         while (true) {
80                 csocket client_command_socket;
81
82                 if (!m_command_channel_accept_socket.accept(client_command_socket)) {
83                         _E("Failed to accept command channel from a client");
84                         continue;
85                 }
86
87                 _D("New client (socket_fd : %d) connected", client_command_socket.get_socket_fd());
88
89                 cmd_worker = new(std::nothrow) command_worker(client_command_socket);
90
91                 if (!cmd_worker) {
92                         _E("Failed to allocate memory");
93                         continue;
94                 }
95
96                 if (!cmd_worker->start())
97                         delete cmd_worker;
98         }
99 }
100
101 void server::accept_event_channel(void)
102 {
103         _I("Event channel acceptor is started");
104
105         while (true) {
106                 csocket client_event_socket;
107
108                 if (!m_event_channel_accept_socket.accept(client_event_socket)) {
109                         _E("Failed to accept event channel from a client");
110                         continue;
111                 }
112
113                 _D("New client(socket_fd : %d) connected", client_event_socket.get_socket_fd());
114
115                 sensor_event_dispatcher::get_instance().accept_event_connections(client_event_socket);
116         }
117 }
118
119 void server::poll_event(void)
120 {
121         _I("Event poller is started");
122
123         sensor_event_poller poller;
124
125         if (!poller.poll()) {
126                 _E("Failed to poll event");
127                 return;
128         }
129 }
130
131 void server::run(void)
132 {
133         m_mainloop = g_main_loop_new(NULL, false);
134
135         sensor_event_dispatcher::get_instance().run();
136
137         listen_command_channel();
138         listen_event_channel();
139
140         thread event_channel_accepter(&server::accept_event_channel, this);
141         event_channel_accepter.detach();
142
143         thread command_channel_accepter(&server::accept_command_channel, this);
144         command_channel_accepter.detach();
145
146         thread event_poller(&server::poll_event, this);
147         event_poller.detach();
148
149         sd_notify(0, "READY=1");
150
151         g_main_loop_run(m_mainloop);
152         g_main_loop_unref(m_mainloop);
153
154         return;
155 }
156
157 bool server::listen_command_channel(void)
158 {
159         int sock_fd = -1;
160         const int MAX_PENDING_CONNECTION = 10;
161
162         sock_fd = get_systemd_socket(COMMAND_CHANNEL_PATH);
163
164         if (sock_fd >= 0) {
165                 _I("Succeeded to get systemd socket(%d)", sock_fd);
166                 m_command_channel_accept_socket = csocket(sock_fd);
167                 return true;
168         }
169
170         INFO("Failed to get systemd socket, create it by myself!");
171         if (!m_command_channel_accept_socket.create(SOCK_STREAM)) {
172                 ERR("Failed to create command channel");
173                 return false;
174         }
175
176         if (!m_command_channel_accept_socket.bind(COMMAND_CHANNEL_PATH)) {
177                 ERR("Failed to bind command channel");
178                 m_command_channel_accept_socket.close();
179                 return false;
180         }
181
182         if (!m_command_channel_accept_socket.listen(MAX_PENDING_CONNECTION)) {
183                 ERR("Failed to listen command channel");
184                 return false;
185         }
186
187         return true;
188 }
189
190 bool server::listen_event_channel(void)
191 {
192         int sock_fd = -1;
193         const int MAX_PENDING_CONNECTION = 32;
194
195         sock_fd = get_systemd_socket(EVENT_CHANNEL_PATH);
196
197         if (sock_fd >= 0) {
198                 _I("Succeeded to get systemd socket(%d)", sock_fd);
199                 m_event_channel_accept_socket = csocket(sock_fd);
200                 return true;
201         }
202
203         INFO("Failed to get systemd socket, create it by myself!");
204
205         if (!m_event_channel_accept_socket.create(SOCK_SEQPACKET)) {
206                 ERR("Failed to create event channel");
207                 return false;
208         }
209
210         if (!m_event_channel_accept_socket.bind(EVENT_CHANNEL_PATH)) {
211                 ERR("Failed to bind event channel");
212                 m_event_channel_accept_socket.close();
213                 return false;
214         }
215
216         if (!m_event_channel_accept_socket.listen(MAX_PENDING_CONNECTION)) {
217                 ERR("Failed to listen event channel");
218                 m_event_channel_accept_socket.close();
219                 return false;
220         }
221
222         return true;
223 }
224
225 void server::stop(void)
226 {
227         if (m_mainloop)
228                 g_main_loop_quit(m_mainloop);
229
230         m_command_channel_accept_socket.close();
231         m_event_channel_accept_socket.close();
232 }
233
234 server& server::get_instance()
235 {
236         static server inst;
237         return inst;
238 }