_E("Received SIGTERM(%d) from %s(%d)\n", signo, proc_name, info->si_pid);
- /* TODO: Refactoring */
- raise(SIGKILL);
+ server::get_instance().stop();
}
static void signal_init(void)
sig_act.sa_sigaction = sig_term_handler;
sig_act.sa_flags = SA_SIGINFO;
sigaction(SIGTERM, &sig_act, NULL);
+ sigaction(SIGABRT, &sig_act, NULL);
+ sigaction(SIGINT, &sig_act, NULL);
}
static void set_cal_data(void)
}
fprintf(fp, "%d", SET_CAL);
- fclose(fp);
+
+ if (fp)
+ fclose(fp);
_I("Succeeded to set calibration data");
set_cal_data();
+ /* TODO: loader has to be moved to server */
sensor_loader::get_instance().load();
server::get_instance().run();
-
server::get_instance().stop();
_I("Sensord terminated");
+
return 0;
}
*
*/
+#include <sys/epoll.h>
+#include <sys/socket.h>
+
#include <systemd/sd-daemon.h>
#include <server.h>
#include <sensor_loader.h>
#include <command_common.h>
#include <command_worker.h>
#include <thread>
-#include <sys/epoll.h>
#include <sensor_event_poller.h>
+#include <client_info_manager.h>
#define SYSTEMD_SOCKET_MAX 2
server::server()
: m_mainloop(NULL)
+, m_running(false)
{
}
server::~server()
{
- stop();
}
int server::get_systemd_socket(const char *name)
void server::accept_command_channel(void)
{
command_worker *cmd_worker;
+
_I("Command channel acceptor is started");
- while (true) {
+ while (m_running) {
csocket client_command_socket;
+ if (!m_command_channel_accept_socket.is_valid()) {
+ _E("Failed to accept, event_channel_accept_socket is closed");
+ break;
+ }
+
if (!m_command_channel_accept_socket.accept(client_command_socket)) {
_E("Failed to accept command channel from a client");
continue;
}
+ if (!m_running) {
+ _E("server die");
+ break;
+ }
+
_D("New client (socket_fd : %d) connected", client_command_socket.get_socket_fd());
+ /* TODO: if socket is closed, it should be erased */
+ client_command_sockets.push_back(client_command_socket);
+
cmd_worker = new(std::nothrow) command_worker(client_command_socket);
if (!cmd_worker) {
_E("Failed to allocate memory");
- continue;
+ break;
}
if (!cmd_worker->start())
delete cmd_worker;
}
+
+ _I("Command channel acceptor is terminated");
}
void server::accept_event_channel(void)
{
- _I("Event channel acceptor is started");
+ _I("Event channel acceptor is started!");
- while (true) {
+ while (m_running) {
csocket client_event_socket;
+ if (!m_event_channel_accept_socket.is_valid()) {
+ _E("Failed to accept, event_channel_accept_socket is closed");
+ break;
+ }
+
if (!m_event_channel_accept_socket.accept(client_event_socket)) {
_E("Failed to accept event channel from a client");
continue;
}
+ if (!m_running) {
+ _E("server die");
+ break;
+ }
+
+ /* TODO: if socket is closed, it should be erased */
+ client_event_sockets.push_back(client_event_socket);
+
_D("New client(socket_fd : %d) connected", client_event_socket.get_socket_fd());
sensor_event_dispatcher::get_instance().accept_event_connections(client_event_socket);
}
+
+ _I("Event channel acceptor is terminated");
}
void server::poll_event(void)
}
}
-void server::run(void)
-{
- m_mainloop = g_main_loop_new(NULL, false);
-
- sensor_event_dispatcher::get_instance().run();
-
- listen_command_channel();
- listen_event_channel();
-
- thread event_channel_accepter(&server::accept_event_channel, this);
- event_channel_accepter.detach();
-
- thread command_channel_accepter(&server::accept_command_channel, this);
- command_channel_accepter.detach();
-
- thread event_poller(&server::poll_event, this);
- event_poller.detach();
-
- sd_notify(0, "READY=1");
-
- g_main_loop_run(m_mainloop);
- g_main_loop_unref(m_mainloop);
-
- return;
-}
-
bool server::listen_command_channel(void)
{
int sock_fd = -1;
return true;
}
-void server::stop(void)
+void server::close_socket(void)
{
- if (m_mainloop)
- g_main_loop_quit(m_mainloop);
-
m_command_channel_accept_socket.close();
m_event_channel_accept_socket.close();
+
+ for (int i = 0; i < client_command_sockets.size(); ++i)
+ client_command_sockets[i].close();
+
+ for (int i = 0; i < client_event_sockets.size(); ++i)
+ client_event_sockets[i].close();
+
+ client_command_sockets.clear();
+ client_event_sockets.clear();
+}
+
+void server::initialize(void)
+{
+ m_running = true;
+ m_mainloop = g_main_loop_new(NULL, false);
+
+ sensor_event_dispatcher::get_instance().run();
+
+ listen_command_channel();
+ listen_event_channel();
+
+ std::thread event_channel_accepter(&server::accept_event_channel, this);
+ event_channel_accepter.detach();
+
+ std::thread command_channel_accepter(&server::accept_command_channel, this);
+ command_channel_accepter.detach();
+
+ std::thread event_poller(&server::poll_event, this);
+ event_poller.detach();
+
+ sd_notify(0, "READY=1");
+
+ g_main_loop_run(m_mainloop);
+}
+
+void server::terminate(void)
+{
+ sensor_event_dispatcher::get_instance().stop();
+
+ close_socket();
+}
+
+void server::run(void)
+{
+ initialize();
+ terminate();
+}
+
+void server::stop(void)
+{
+ _I("Sensord server stopped");
+
+ m_running = false;
+
+ if (m_mainloop) {
+ g_main_loop_quit(m_mainloop);
+ g_main_loop_unref(m_mainloop);
+ m_mainloop = NULL;
+ }
}
server& server::get_instance()
bool csocket::accept(csocket& client_socket) const
{
+ const int TIMEOUT = 1;
+ struct timeval tv;
int addr_length = sizeof(m_addr);
int err = 0;
+ fd_set read_fds;
+
+ while (true) {
+ FD_ZERO(&read_fds);
+ FD_SET(m_sock_fd, &read_fds);
+
+ tv.tv_sec = TIMEOUT;
+ tv.tv_usec = 0;
+
+ err = ::select(m_sock_fd + 1, &read_fds, NULL, NULL, &tv);
+ if (err == -1) {
+ _ERRNO(errno, _E, "Failed to select(), m_sock_fd : %d", m_sock_fd);
+ return false;
+ }
+
+ if (!is_valid()) {
+ _E("socket is closed, m_sock_fd : %d", m_sock_fd);
+ return false;
+ }
+
+ /* timeout */
+ if (!err)
+ continue;
+
+ if (FD_ISSET(m_sock_fd, &read_fds))
+ break;
+
+ _ERRNO(errno, _E, "Failed to select(), msock_fd : %d", m_sock_fd);
+ }
+
+ if (!is_valid()) {
+ _E("socket is closed, m_sock_fd : %d", m_sock_fd);
+ return false;
+ }
+
do {
client_socket.m_sock_fd = ::accept(m_sock_fd, (sockaddr *)&m_addr, (socklen_t *)&addr_length);
if (!client_socket.is_valid())
ssize_t err, len;
do {
- len = ::recv(m_sock_fd, buffer, size, m_recv_flags);
+ len = ::recv(m_sock_fd, buffer, size, m_recv_flags);
if (len > 0) {
err = 0;
} else {
err = errno;
}
- } while (err == EINTR);
+ } while (err == EINTR);
- if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
- _ERRNO(err, _D, "Failed to recv(%d, %#x, %d, %#x) = %d",
- m_socket_fd, buffer, size, m_recv_flags, len);
+ if ((err == EAGAIN) || (err == EWOULDBLOCK))
return 0;
- }
if (err) {
_ERRNO(err, _E, "Failed to recv(%d, %#x, %d, %#x) = %d",
m_sock_fd, buffer, size, m_recv_flags, len);
}
- return err == 0 ? len : -err;
+ return err == 0 ? len : -err;
}
ssize_t csocket::send_for_stream(const void *buffer, size_t size) const