server.cpp 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #include <boost/bind.hpp>
  2. #include <boost/make_shared.hpp>
  3. #include <iostream>
  4. #include <sys/wait.h>
  5. #include "server.h"
  6. server::server(boost::asio::io_service& ioService, unsigned short port, const std::string& path, const std::string& url) :
  7. m_ioService(ioService),
  8. m_signal(ioService, SIGCHLD),
  9. m_acceptor(ioService, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)),
  10. m_socket(ioService)
  11. {
  12. m_context.path = path;
  13. m_context.url = url;
  14. start_signal_wait();
  15. start_accept();
  16. }
  17. void server::start_signal_wait()
  18. {
  19. m_signal.async_wait(boost::bind(&server::handle_signal_wait, this));
  20. }
  21. void server::handle_signal_wait()
  22. {
  23. // Only the parent process should check for this signal. We can determine
  24. // whether we are in the parent by checking if the acceptor is still open.
  25. if (m_acceptor.is_open())
  26. {
  27. // Reap completed child processes so that we don't end up with zombies.
  28. int status = 0;
  29. while (waitpid(-1, &status, WNOHANG) > 0) {}
  30. start_signal_wait();
  31. }
  32. }
  33. void server::start_accept()
  34. {
  35. m_connection.reset(new connection(m_ioService, m_context));
  36. m_acceptor.async_accept(m_connection->socket(), boost::bind(&server::handle_accept, this, _1));
  37. }
  38. void server::handle_accept(const boost::system::error_code& ec)
  39. {
  40. if (!ec)
  41. {
  42. m_ioService.notify_fork(boost::asio::io_service::fork_prepare);
  43. if (fork() == 0)
  44. {
  45. m_ioService.notify_fork(boost::asio::io_service::fork_child);
  46. m_acceptor.close();
  47. m_signal.cancel();
  48. m_connection->start();
  49. }
  50. else
  51. {
  52. m_ioService.notify_fork(boost::asio::io_service::fork_parent);
  53. m_connection.reset();
  54. m_socket.close();
  55. start_accept();
  56. }
  57. }
  58. else
  59. {
  60. std::cout << "Accept error: " << ec.message() << std::endl;
  61. start_accept();
  62. }
  63. }