Server.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include "Server.h"
  2. #include <Logging.h>
  3. #include <functional>
  4. #include <sstream>
  5. #include <sys/wait.h>
  6. namespace MailServer {
  7. Server::Server(asio::io_service& ioService, unsigned short port, const std::string& path, const std::string& url) :
  8. m_ioService(ioService),
  9. m_signal(ioService, SIGCHLD),
  10. m_acceptor(ioService, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port)),
  11. m_socket(ioService)
  12. {
  13. m_context.path = path;
  14. m_context.url = url;
  15. StartSignalWait();
  16. StartAccept();
  17. }
  18. void Server::StartSignalWait()
  19. {
  20. m_signal.async_wait(std::bind(&Server::HandleSignalWait, this));
  21. }
  22. void Server::HandleSignalWait()
  23. {
  24. // Only the parent process should check for this signal. We can determine
  25. // whether we are in the parent by checking if the acceptor is still open.
  26. if (m_acceptor.is_open())
  27. {
  28. // Reap completed child processes so that we don't end up with zombies.
  29. int status = 0;
  30. while (waitpid(-1, &status, WNOHANG) > 0) {}
  31. StartSignalWait();
  32. }
  33. }
  34. void Server::StartAccept()
  35. {
  36. m_connection.reset(new Connection(m_ioService, m_context));
  37. m_acceptor.async_accept(m_connection->Socket(), std::bind(&Server::HandleAccept, this, std::placeholders::_1));
  38. }
  39. void Server::HandleAccept(const asio::error_code& ec)
  40. {
  41. if (!ec)
  42. {
  43. m_ioService.notify_fork(asio::io_service::fork_prepare);
  44. if (fork() == 0)
  45. {
  46. m_ioService.notify_fork(asio::io_service::fork_child);
  47. m_acceptor.close();
  48. m_signal.cancel();
  49. m_connection->Start();
  50. }
  51. else
  52. {
  53. m_ioService.notify_fork(asio::io_service::fork_parent);
  54. m_connection.reset();
  55. m_socket.close();
  56. StartAccept();
  57. }
  58. }
  59. else
  60. {
  61. std::stringstream ss;
  62. ss << "Server::HandleAccept() - Error" << std::endl;
  63. Logging::Log(Logging::Severity::Error, ss.str());
  64. StartAccept();
  65. }
  66. }
  67. } // namespace MailServer