stop thread before socket destructor

Hi All, I modified a boost example to implement a tcp server that's able to accept clients on a thread. Unfortunately I get the following message: "The I/O operation has been aborted because of either a thread exit or an application request". I realized that the problem is related to the fact the server destructor is called before the handle_accept occurs. Now, how could I stop the thread in the server destructor so that the handle_accept is not called anymore? Here is the test code I used: typedef boost::shared_ptrboost::asio::ip::tcp::socket tcp_socket_ptr; class stream_handler { public: stream_handler() : acceptor_(io_service_) { boost::asio::ip::tcp::endpoint endpoint = boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 32123); acceptor_.open(endpoint.protocol()); acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); acceptor_.bind(endpoint); acceptor_.listen(); new_socket = tcp_socket_ptr(new boost::asio::ip::tcp::socket(io_service_)); acceptor_.async_accept(*new_socket, boost::bind(&stream_handler::handle_accept, this, boost::asio::placeholders::error)); thread_ = boost::thread(boost::bind(&boost::asio::io_service::run, &io_service_)); } ~stream_handler() { acceptor_.close(); } void handle_accept(const boost::system::error_code& err) { if (err) { std::cout << err.message() << std::endl; } else { new_socket = tcp_socket_ptr(new boost::asio::ip::tcp::socket(io_service_)); acceptor_.async_accept(*new_socket, boost::bind(&stream_handler::handle_accept, this, boost::asio::placeholders::error)); } } private: io_service io_service_; tcp::acceptor acceptor_; boost::thread thread_; tcp_socket_ptr new_socket; }; int _tmain(int argc, _TCHAR* argv[]) { stream_handler sh; return 0; } Regards Gianni

Il 4/28/2011 12:21 AM, Igor R ha scritto:
Now, how could I stop the thread in the server destructor so that the handle_accept is not called anymore? You can wait until io_service::run() exits:
~stream_handler() { acceptor_.close();
//... thread_.join(); }
I think that would not prevent the handle_accept to be called after the server destructor, with an error code related to the message I told you in the previous email. I find a solution in a different way, using the boost::asio::io_service::work. I added a member variable: boost::asio::io_service::work work_; I instanciated it in the server constructor as follows: work_(io_service_) Then in the server destructor: ~stream_handler() { io_service_.stop(); } That seems working and the handle_accept is never called after the destructor. Thanks, Gianni
participants (2)
-
Gianni Ambrosio
-
Igor R