Raise asio http server, how to stop?

I work with one of the examples of http-servers that come with boost (in doc / html / boost_asio / example / cpp03 / http / server or alternately at http://www.boost.org/doc/libs/1_55_0/doc/ html / boost_asio / examples / cpp03_examples.html # boost_asio.examples.cpp03_examples.http_server ).

In this example, the acceptor socket is opened and listened, discarding requests for requesting objects. The server also supports asio signal_set , which registers signal handlers and cancels all asio requests from io_service upon receipt of SIGINT or SIGTERM. Press CTRL-C and a signal is received, io_service calls the handle_stop() function, which then calls .close() on all asio::ip::tcp::sockets . The entire server shuts down gracefully, the io_service.run() exits exit, and the program ends.

I would like to run this HTTP server in a stream, and then cancel it programmatically, rather than using signals. What is an acceptable way to do this? I removed signal_set and signal handlers, and then started the server in another thread. It handles HTTP requests quite well from this new thread. How to stop it from another thread? Can I call asio::ip::tcp::socket::close() from another thread? The documentation is unclear, and only that is very good, un-asio-ish. Indeed, when I try to do this, it works well, until I have accepted any HTTP requests. If I process at least one HTTP request, the process will work a lot:

 > test_ssl_server_sa.exe!boost::detail::sp_counted_base::add_ref_lock() Line 81 + 0x3 bytes C++ test_ssl_server_sa.exe!boost::detail::shared_count::shared_count(const boost::detail::weak_count & r={...}) Line 578 + 0x12 bytes C++ test_ssl_server_sa.exe!boost::shared_ptr<http::server::connection>::shared_ptr<http::server::connection><http::server::connection>(const boost::weak_ptr<http::server::connection> & r={...}) Line 405 + 0x3f bytes C++ test_ssl_server_sa.exe!boost::enable_shared_from_this<http::server::connection>::shared_from_this() Line 49 + 0xc bytes C++ test_ssl_server_sa.exe!http::server::connection::handle_handshake(const boost::system::error_code & error={...}) Line 83 + 0x11 bytes C++ test_ssl_server_sa.exe!boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>::operator()(http::server::connection * p=0x004b8fe8, const boost::system::error_code & a1={...}) Line 165 + 0x18 bytes C++ test_ssl_server_sa.exe!boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> >::operator()<boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list1<boost::system::error_code const &> >(boost::_bi::type<void> __formal={...}, boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &> & f={...}, boost::_bi::list1<boost::system::error_code const &> & a={...}, boost::_bi::type<void> __formal={...}) Line 314 C++ test_ssl_server_sa.exe!boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > >::operator()<boost::system::error_code>(const boost::system::error_code & a1={...}) Line 48 C++ test_ssl_server_sa.exe!boost::asio::ssl::detail::handshake_op::call_handler<boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >(boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > & handler={...}, const boost::system::error_code & ec={...}, const unsigned int & __formal=0) Line 55 C++ test_ssl_server_sa.exe!boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >::operator()(boost::system::error_code ec={...}, unsigned int bytes_transferred=0, int start=0) Line 276 C++ test_ssl_server_sa.exe!boost::asio::detail::binder2<boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >,boost::system::error_code,unsigned int>::operator()() Line 129 C++ test_ssl_server_sa.exe!boost::asio::asio_handler_invoke<boost::asio::detail::binder2<boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >,boost::system::error_code,unsigned int> >(boost::asio::detail::binder2<boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >,boost::system::error_code,unsigned int> & function={...}, ...) Line 70 C++ test_ssl_server_sa.exe!boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder2<boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >,boost::system::error_code,unsigned int>,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >(boost::asio::detail::binder2<boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >,boost::system::error_code,unsigned int> & function={...}, boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > & context={...}) Line 37 + 0x16 bytes C++ test_ssl_server_sa.exe!boost::asio::ssl::detail::asio_handler_invoke<boost::asio::detail::binder2<boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >,boost::system::error_code,unsigned int>,boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >(boost::asio::detail::binder2<boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >,boost::system::error_code,unsigned int> & function={...}, boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > > * this_handler=0x00fefb70) Line 319 + 0x10 bytes C++ test_ssl_server_sa.exe!boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder2<boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >,boost::system::error_code,unsigned int>,boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > > >(boost::asio::detail::binder2<boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >,boost::system::error_code,unsigned int> & function={...}, boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > > & context={...}) Line 37 + 0x16 bytes C++ test_ssl_server_sa.exe!boost::asio::detail::reactive_socket_recv_op<boost::asio::mutable_buffers_1,boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > > >::do_complete(boost::asio::detail::task_io_service * owner=0x00c1aca0, boost::asio::detail::task_io_service_operation * base=0x00c1f948, const boost::system::error_code & __formal={...}, const boost::system::error_code & __formal={...}) Line 110 + 0xd bytes C++ test_ssl_server_sa.exe!boost::asio::detail::task_io_service_operation::complete(boost::asio::detail::task_io_service & owner={...}, const boost::system::error_code & ec={...}, unsigned int bytes_transferred=0) Line 38 + 0x1a bytes C++ test_ssl_server_sa.exe!boost::asio::detail::task_io_service::do_run_one(boost::asio::detail::scoped_lock<boost::asio::detail::win_mutex> & lock={...}, boost::asio::detail::task_io_service_thread_info & this_thread={...}, const boost::system::error_code & ec={...}) Line 386 C++ test_ssl_server_sa.exe!boost::asio::detail::task_io_service::run(boost::system::error_code & ec={...}) Line 153 + 0x1e bytes C++ 

I'm not saying that the server may have another synchronization problem - in particular, it seems that the server is crashing with multiple access on boost::shared_ptr to the connection object. But I'm more interested in what would be the correct way to disconnect the asio io_service.run() call from another thread. When I imagine how I like it, I present an io_service request that is waiting for a control variable. If I wanted to close the server, I would pass the control variable from another thread, and io_service will call my callback in the io_service thread. From there, he could .close() create any sockets or otherwise cancel any other requests in flight.

+5
source share
1 answer

You can use boost :: asio :: io_service :: post with lambda from a thread trying to stop the HTTP server. The lambda will be executed in the HTTP server thread. It can safely call socket :: close on all sockets. This will elegantly stop the service.

0
source

Source: https://habr.com/ru/post/1200506/


All Articles