Skip to content

Instantly share code, notes, and snippets.

@Chaosvex
Last active February 16, 2018 21:07
Show Gist options
  • Save Chaosvex/0a41bc72a9dabcfe761d9e29b1827c30 to your computer and use it in GitHub Desktop.
Save Chaosvex/0a41bc72a9dabcfe761d9e29b1827c30 to your computer and use it in GitHub Desktop.
void ClientConnection::stop() {
LOG_DEBUG_FILTER(logger_, LF_NETWORK)
<< "Closing connection to " << remote_address() << LOG_ASYNC;
handler_.stop();
boost::system::error_code ec; // we don't care about any errors
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
socket_.close(ec);
stopped_ = true;
}
/*
* This function should only be used by the handler to allow for the session to be
* queued for closure after it has returned from processing the current event/packet.
* Posting rather than dispatching ensures that the object won't be destroyed by the
* session manager until current processing has finished.
*/
void ClientConnection::close_session() {
service_.post([this] {
sessions_.stop(this);
});
}
/*
* This function is used by the destructor to ensure that all current processing
* has finished before it returns. It uses dispatch rather than post to ensure
* that if the calling thread happens to be the owner of this connection, that
* it will be closed immediately, 'in line', rather than blocking indefinitely.
*/
void ClientConnection::close_session_sync() {
service_.dispatch([&] {
stop();
std::unique_lock<std::mutex> ul(stop_lock_);
stop_condvar_.notify_all();
});
}
void ClientConnection::terminate() {
if(!stopped_) {
close_session_sync();
while(!stopped_) {
std::unique_lock<std::mutex> guard(stop_lock_);
stop_condvar_.wait(guard);
}
}
}
/*
* Closes the socket and then posts a final event that keeps the client alive
* until all pending handlers are executed with 'operation_aborted'.
* That's the theory anyway.
*/
void ClientConnection::async_shutdown(std::unique_ptr<ClientConnection> client) {
client->terminate();
client->service_.post([client]() {
LOG_TRACE_FILTER_GLOB(LF_NETWORK) << "Handler for " << client->remote_address()
<< " destroyed" << LOG_ASYNC;
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment