Re: [boost] .[asio] : Problem while clean shut down of multi threaded server

On Mon, 21 May 2007 16:37:28 +0530, Gaurav.Jain <at> iflexsolutions.com said:
Hi,
I am using boost boost 1.33.1 with asio 0.3.8rc2. I have develop a Multi-threaded server program using pool of io_service. In my design i have pool of io_service object and this pool is controlled by a pool manager, which is running over a seprate io_service. I want to do clean shutdown of the server. In the clean shut down i want to close each connection running over related io_service.
It's worth noting that this is not the only way to do clean shutdown. The new HTTP server examples ("server2" and "server3") also perform a clean shutdown. However, rather than explicitly closing the connections, they simply rely on the fact that the io_service destructor will destroy all handler objects associated with unfinished operations.
What i am doing is, while shutting down the server, pool manager is posting a request to each io_service object to shut it down. Each io_service object in turn posting a request to all the connection it is hosting to stop themselves. The problem i am facing : connection stop method is not getting executed at all for each running connection.
Here is a code snippet of what i am doing : [...] scheduler.stop();
What is scheduler? Is it an io_service? If so, by explicitly stopping it some of your completion handlers will never be called. If you want to use this particular clean shutdown design, it is better to wait for the io_service::run() call to finish automatically once all the outstanding operations have finished
Yes scheduler is an io_service. I am now not using scheduler.stop() in my code & doing what have you suggested in your reply. But still server is not getting cleanly shutdown as per my design. Here is what am I doing : void tcp_server::handle_stop() { acceptor_.close(); if(io_object_pool_) { delete io_object_pool_; io_object_pool_ = NULL; } } io_object_pool::~io_object_pool() { shutdown_pool(); } void io_object_pool::shutdown_pool() { std::vector<io_object*>::const_iterator iter_output = io_object_vec.begin(); std::vector<io_object*>::const_iterator iter_end_output = io_object_vec.end(); for(; iter_output != iter_end_output; ) { io_object* io_object_temp = *iter_output; iter_output++; io_object_temp->get_ioservice().post(boost::bind(&io_object::stop_all, io_object_temp)); } io_object_vec.clear(); } void io_object::stop_all() { std::set<connection_ptr >::const_iterator iter_output = connections_.begin(); std::set<connection_ptr >::const_iterator iter_end_output = connections_.end(); for(; iter_output != iter_end_output;) { connection_ptr conn_temp = *iter_output; iter_output++; conn_temp->socket().io_service().post(boost::bind(&tcp_connection::stop, conn_temp)); } //scheduler.stop(); execution_thread->join(); } In above code I have also tried with io_service().wrap() instead of post(), but all in vein void tcp_connection::stop() { try { std::cout << "tcp_connection stop called" << std::endl; assigned_io_object_->stop(shared_from_this()); socket_.close(); assigned_io_object_->remove_request(); assigned_io_object_ = NULL; is_connection_stop = true; } catch (std::exception&) { } } The above cout statement is not getting printed, not even for single connection. Can you pls suggest what else is getting wrong here Regards, Gaurav DISCLAIMER: This message contains privileged and confidential information and is intended only for an individual named. If you are not the intended recipient, you should not disseminate, distribute, store, print, copy or deliver this message. Please notify the sender immediately by e-mail if you have received this e-mail by mistake and delete this e-mail from your system. E-mail transmission cannot be guaranteed to be secure or error-free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete or contain viruses. The sender, therefore, does not accept liability for any errors or omissions in the contents of this message which arise as a result of e-mail transmission. If verification is required, please request a hard-copy version.

On Tue, 22 May 2007 20:30:01 +0530, Gaurav.Jain@iflexsolutions.com said:
Yes scheduler is an io_service. I am now not using scheduler.stop() in my code & doing what have you suggested in your reply. But still server is not getting cleanly shutdown as per my design. Here is what am I doing :
You are posting the io_object::stop_all() call into the io_service here:
io_object_temp->get_ioservice().post(boost::bind(&io_object::stop_all, io_object_temp));
and then inside io_object::stop_all() you attempt to join() the thread that is calling io_service::run():
execution_thread->join();
Since the io_service executes posted handlers inside io_service::run(), this may mean you are trying to join the thread from within the thread itself. I suggest moving the join() call to io_object_pool::stop_all() so that it is performed outside of the io_service::run() thread. Cheers, Chris
participants (2)
-
Christopher Kohlhoff
-
Gaurav.Jain@iflexsolutions.com