| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- #include "Server.h"
- #include <Logging.h>
- #include <functional>
- #include <sstream>
- #include <sys/wait.h>
- namespace MailServer {
- Server::Server(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, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port)),
- m_socket(ioService)
- {
- m_context.path = path;
- m_context.url = url;
- StartSignalWait();
- StartAccept();
- }
- void Server::StartSignalWait()
- {
- m_signal.async_wait(std::bind(&Server::HandleSignalWait, this));
- }
- void Server::HandleSignalWait()
- {
- // 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) {}
- StartSignalWait();
- }
- }
- void Server::StartAccept()
- {
- m_connection.reset(new Connection(m_ioService, m_context));
- m_acceptor.async_accept(m_connection->Socket(), std::bind(&Server::HandleAccept, this, std::placeholders::_1));
- }
- void Server::HandleAccept(const asio::error_code& ec)
- {
- if (!ec)
- {
- m_ioService.notify_fork(asio::io_service::fork_prepare);
- if (fork() == 0)
- {
- m_ioService.notify_fork(asio::io_service::fork_child);
- m_acceptor.close();
- m_signal.cancel();
- m_connection->Start();
- }
- else
- {
- m_ioService.notify_fork(asio::io_service::fork_parent);
- m_connection.reset();
- m_socket.close();
- StartAccept();
- }
- }
- else
- {
- std::stringstream ss;
- ss << "Server::HandleAccept() - Error" << std::endl;
- Logging::Log(Logging::Severity::Error, ss.str());
- StartAccept();
- }
- }
- } // namespace MailServer
|