Files
AlarmServer/server.cpp
T
2017-04-28 18:45:26 +02:00

76 lines
1.7 KiB
C++

#include <boost/bind.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
#include <sys/wait.h>
#include "server.h"
server::server(boost::asio::io_service& ioService, unsigned short port, const std::string& path, const std::string& url) :
m_ioService(ioService),
m_signal(ioService, SIGCHLD),
m_acceptor(ioService, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)),
m_socket(ioService)
{
m_context.path = path;
m_context.url = url;
start_signal_wait();
start_accept();
}
void server::start_signal_wait()
{
m_signal.async_wait(boost::bind(&server::handle_signal_wait, this));
}
void server::handle_signal_wait()
{
// Only the parent process should check for this signal. We can determine
// whether we are in the parent by checking if the acceptor is still open.
if (m_acceptor.is_open())
{
// Reap completed child processes so that we don't end up with zombies.
int status = 0;
while (waitpid(-1, &status, WNOHANG) > 0) {}
start_signal_wait();
}
}
void server::start_accept()
{
m_connection.reset(new connection(m_ioService, m_context));
m_acceptor.async_accept(m_connection->socket(), boost::bind(&server::handle_accept, this, _1));
}
void server::handle_accept(const boost::system::error_code& ec)
{
if (!ec)
{
m_ioService.notify_fork(boost::asio::io_service::fork_prepare);
if (fork() == 0)
{
m_ioService.notify_fork(boost::asio::io_service::fork_child);
m_acceptor.close();
m_signal.cancel();
m_connection->start();
}
else
{
m_ioService.notify_fork(boost::asio::io_service::fork_parent);
m_connection.reset();
m_socket.close();
start_accept();
}
}
else
{
std::cout << "Accept error: " << ec.message() << std::endl;
start_accept();
}
}