| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- #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();
- }
- }
|