c++ - How do I send a SIGTERM or SIGINT signal to the server in the boost HTML3 example? -


i using html server 3 example boost learning tool (http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/examples.html#boost_asio.examples.http_server_3) asynchronous message handling.

i have taken example, , turned library server object can instantiate in programs. thing have done above example remove main.cpp , compile library. , works extend can instantiate server object in code, , pass messages command line.

where struggling how terminate server gracefully. sample code see this:

server::server(const std::string& address, const std::string& port,                  std::size_t thread_pool_size,                handler &handler)           : thread_pool_size_(thread_pool_size),             signals_(io_service_),             acceptor_(io_service_),             new_connection_(),             request_handler_(handler)   {     // register handle signals indicate when server should exit.     // safe register same signal multiple times in program,     // provided registration specified signal made through asio.     signals_.add(sigint);     signals_.add(sigterm);     signals_.async_wait(boost::bind(&server::handle_stop, this)); 

so asynchronous thread set listen signals , respond them

i have implemented server object in thread in program follows:

class serverworker { public:     serverworker(std::string thehost, std::string theport)     {         host = thehost;         port = theport;     }     void start()     {         try         {             myrequesthandler handler;             int ncores = boost::thread::hardware_concurrency();             server *mserver = new server(host, port, ncores, handler);             svr->run();         }         catch(std::exception &e) { /* */ }     }     void stop()     {         mserver->stop(); // should raise signal , send server                          // don't know how     } private:     std::string host;     std::string port;     server *mserver; };  test(bsgt_lbsserver_stress, bsgt_singleton) {     // launch server on new thread     serverworker sw(bsgt_default_ipaddress, bsgt_default_port_str);     boost::function<void()> th_func = boost::bind(&serverworker::start, &sw);     boost::thread swthread = boost::thread(th_func);      //      // how signal server in swthread stop?     } 

how implement stop() method on server object send signal itself? have tried:
1) raise(sigterm) - kills whole program
2) raise(sigint) - kills whole program

raise() appropriate having process signal itself.

void serverworker::stop() {   std::raise(sigterm); } 

be aware raise() asynchronous. issue signal , return immediately. hence, control may continue before io_service processes enqueued signalhandler.

void run_server() {   // launch server on new thread   serverworker server_worker(...);   boost::thread worker_thread([&server_worker]() { server_worker.start(); });    ...    // raises sigterm.  may return before io_service stopped.   server_worker.stop();    // need synchronize worker_thread.  `worker_thread` may still   // in `serverworker::start()` go out of scope.  additionally,   // `worker_thread` joinable, destructor may invoke    // `std::terminate()`. } 

here minimal example demonstrating using boost.asio signal handling, raise(), , synchronization:

#include <cassert> #include <csignal> #include <iostream> #include <thread> #include <boost/asio.hpp>  int main() {   boost::asio::io_service io_service;    // prevent io_service running out of work.   boost::asio::io_service::work work(io_service);    // boost.asio register internal handler sigterm.   boost::asio::signal_set signal_set(io_service, sigterm);   signal_set.async_wait(     [&io_service](        const boost::system::error_code& error,        int signal_number)     {       std::cout << "got signal " << signal_number << "; "                    "stopping io_service." << std::endl;       io_service.stop();     });    // raise sigterm.   std::raise(sigterm);    // time raise() returns, boost.asio has handled sigterm   // own internal handler, queuing internally.  @ point, boost.asio   // ready dispatch notification user signal handler   // (i.e. provided signal_set.async_wait()) within   // io_service event loop.   std::cout << "io_service stopped? " << io_service.stopped() << std::endl;   assert(false == io_service.stopped());    // initiate thread run io_service.  invoke   // queued handler ready completion.   std::thread work_thread([&io_service]() { io_service.run(); });    // synchornize on work_thread.  letting run completion.   work_thread.join();    // io_service has been explicitly stopped in async_wait   // handler.   std::cout << "io_service stopped? " << io_service.stopped() << std::endl;   assert(true == io_service.stopped()); } 

output:

io_service stopped? 0 got signal 15; stopping io_service. io_service stopped? 1 

Comments