diff --git a/example/http/server/server.cpp b/example/http/server/server.cpp index 0b9ced65..d988cb3b 100644 --- a/example/http/server/server.cpp +++ b/example/http/server/server.cpp @@ -57,13 +57,6 @@ void server::run() io_service_.run(); } -void server::stop() -{ - // Post a call to the stop function so that server::stop() is safe to call - // from any thread. - io_service_.post(boost::bind(&server::handle_stop, this)); -} - void server::handle_accept(const boost::system::error_code& e) { if (!e) diff --git a/example/http/server/server.hpp b/example/http/server/server.hpp index 9b09c621..95a5c426 100644 --- a/example/http/server/server.hpp +++ b/example/http/server/server.hpp @@ -34,9 +34,6 @@ public: /// Run the server's io_service loop. void run(); - /// Stop the server. - void stop(); - private: /// Handle completion of an asynchronous accept operation. void handle_accept(const boost::system::error_code& e); diff --git a/example/http/server2/main.cpp b/example/http/server2/main.cpp index 6381ebc6..550adaf8 100644 --- a/example/http/server2/main.cpp +++ b/example/http/server2/main.cpp @@ -20,13 +20,13 @@ int main(int argc, char* argv[]) try { // Check command line arguments. - if (argc != 4) + if (argc != 5) { - std::cerr << "Usage: http_server
\n"; + std::cerr << "Usage: http_server
\n"; std::cerr << " For IPv4, try:\n"; - std::cerr << " receiver 0.0.0.0 80 .\n"; + std::cerr << " receiver 0.0.0.0 80 1 .\n"; std::cerr << " For IPv6, try:\n"; - std::cerr << " receiver 0::0 80 .\n"; + std::cerr << " receiver 0::0 80 1 .\n"; return 1; } diff --git a/example/http/server2/server.cpp b/example/http/server2/server.cpp index 0a0dd4de..10bae34f 100644 --- a/example/http/server2/server.cpp +++ b/example/http/server2/server.cpp @@ -17,11 +17,22 @@ namespace server2 { server::server(const std::string& address, const std::string& port, const std::string& doc_root, std::size_t io_service_pool_size) : io_service_pool_(io_service_pool_size), + signals_(io_service_pool_.get_io_service()), acceptor_(io_service_pool_.get_io_service()), new_connection_(new connection( io_service_pool_.get_io_service(), request_handler_)), request_handler_(doc_root) { + // Register to handle the signals that indicate when the server should exit. + // It is safe to register for the same signal multiple times in a program, + // provided all registration for the specified signal is made through Asio. + signals_.add(SIGINT); + signals_.add(SIGTERM); +#if defined(SIGQUIT) + signals_.add(SIGQUIT); +#endif // defined(SIGQUIT) + signals_.async_wait(boost::bind(&server::handle_stop, this)); + // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR). boost::asio::ip::tcp::resolver resolver(acceptor_.get_io_service()); boost::asio::ip::tcp::resolver::query query(address, port); @@ -40,11 +51,6 @@ void server::run() io_service_pool_.run(); } -void server::stop() -{ - io_service_pool_.stop(); -} - void server::handle_accept(const boost::system::error_code& e) { if (!e) @@ -58,5 +64,10 @@ void server::handle_accept(const boost::system::error_code& e) } } +void server::handle_stop() +{ + io_service_pool_.stop(); +} + } // namespace server2 } // namespace http diff --git a/example/http/server2/server.hpp b/example/http/server2/server.hpp index 3aeef0d5..6f6db5d1 100644 --- a/example/http/server2/server.hpp +++ b/example/http/server2/server.hpp @@ -36,16 +36,19 @@ public: /// Run the server's io_service loop. void run(); - /// Stop the server. - void stop(); - private: /// Handle completion of an asynchronous accept operation. void handle_accept(const boost::system::error_code& e); + /// Handle a request to stop the server. + void handle_stop(); + /// The pool of io_service objects used to perform asynchronous operations. io_service_pool io_service_pool_; + /// The signal_set is used to register for process termination notifications. + boost::asio::signal_set signals_; + /// Acceptor used to listen for incoming connections. boost::asio::ip::tcp::acceptor acceptor_; diff --git a/example/http/server3/main.cpp b/example/http/server3/main.cpp index 3438657f..c8aff867 100644 --- a/example/http/server3/main.cpp +++ b/example/http/server3/main.cpp @@ -20,13 +20,13 @@ int main(int argc, char* argv[]) try { // Check command line arguments. - if (argc != 4) + if (argc != 5) { - std::cerr << "Usage: http_server
\n"; + std::cerr << "Usage: http_server
\n"; std::cerr << " For IPv4, try:\n"; - std::cerr << " receiver 0.0.0.0 80 .\n"; + std::cerr << " receiver 0.0.0.0 80 1 .\n"; std::cerr << " For IPv6, try:\n"; - std::cerr << " receiver 0::0 80 .\n"; + std::cerr << " receiver 0::0 80 1 .\n"; return 1; } diff --git a/example/http/server3/server.cpp b/example/http/server3/server.cpp index ef9bef51..a580021b 100644 --- a/example/http/server3/server.cpp +++ b/example/http/server3/server.cpp @@ -20,10 +20,21 @@ namespace server3 { server::server(const std::string& address, const std::string& port, const std::string& doc_root, std::size_t thread_pool_size) : thread_pool_size_(thread_pool_size), + signals_(io_service_), acceptor_(io_service_), new_connection_(new connection(io_service_, request_handler_)), request_handler_(doc_root) { + // Register to handle the signals that indicate when the server should exit. + // It is safe to register for the same signal multiple times in a program, + // provided all registration for the specified signal is made through Asio. + signals_.add(SIGINT); + signals_.add(SIGTERM); +#if defined(SIGQUIT) + signals_.add(SIGQUIT); +#endif // defined(SIGQUIT) + signals_.async_wait(boost::bind(&server::handle_stop, this)); + // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR). boost::asio::ip::tcp::resolver resolver(io_service_); boost::asio::ip::tcp::resolver::query query(address, port); @@ -53,11 +64,6 @@ void server::run() threads[i]->join(); } -void server::stop() -{ - io_service_.stop(); -} - void server::handle_accept(const boost::system::error_code& e) { if (!e) @@ -70,5 +76,10 @@ void server::handle_accept(const boost::system::error_code& e) } } +void server::handle_stop() +{ + io_service_.stop(); +} + } // namespace server3 } // namespace http diff --git a/example/http/server3/server.hpp b/example/http/server3/server.hpp index ac2cbaa3..95314c1d 100644 --- a/example/http/server3/server.hpp +++ b/example/http/server3/server.hpp @@ -35,19 +35,22 @@ public: /// Run the server's io_service loop. void run(); - /// Stop the server. - void stop(); - private: /// Handle completion of an asynchronous accept operation. void handle_accept(const boost::system::error_code& e); + /// Handle a request to stop the server. + void handle_stop(); + /// The number of threads that will call io_service::run(). std::size_t thread_pool_size_; /// The io_service used to perform asynchronous operations. boost::asio::io_service io_service_; + /// The signal_set is used to register for process termination notifications. + boost::asio::signal_set signals_; + /// Acceptor used to listen for incoming connections. boost::asio::ip::tcp::acceptor acceptor_;