Bug #11302 » 0004-Track-closing-tcp-connections-to-avoid-race.patch
src/http/Server.C | ||
---|---|---|
* Ssl connection, this performance impact is negligible (and both
|
||
* need to access the ConnectionManager mutex in any case).
|
||
*/
|
||
for (std::size_t i = 0; i < tcp_listeners_.size(); ++i) {
|
||
asio::ip::tcp::acceptor &acceptor = tcp_listeners_[i].acceptor;
|
||
TcpConnectionPtr &new_connection = tcp_listeners_[i].new_connection;
|
||
for (auto &&tcp_listener: tcp_listeners_) {
|
||
asio::ip::tcp::acceptor &acceptor = tcp_listener.acceptor;
|
||
TcpConnectionPtr &new_connection = tcp_listener.new_connection;
|
||
acceptor.async_accept(new_connection->socket(),
|
||
accept_strand_.wrap(
|
||
std::bind(&Server::handleTcpAccept, this,
|
||
&tcp_listeners_[i],
|
||
&tcp_listener,
|
||
std::placeholders::_1)));
|
||
}
|
||
... | ... | |
void Server::handleResume()
|
||
{
|
||
for (std::size_t i = 0; i < tcp_listeners_.size(); ++i)
|
||
tcp_listeners_[i].acceptor.close();
|
||
tcp_listeners_.clear();
|
||
for (auto &&tcp_listener: tcp_listeners_)
|
||
tcp_listener.acceptor.close();
|
||
tcp_listeners_closed_.splice(tcp_listeners_closed_.end(), tcp_listeners_);
|
||
#ifdef HTTP_WITH_SSL
|
||
for (std::size_t i = 0; i < ssl_listeners_.size(); ++i)
|
||
... | ... | |
} else if (!listener->acceptor.is_open()) {
|
||
// server shutdown
|
||
LOG_DEBUG("handleTcpAccept: async_accept error (acceptor closed, probably server shutdown): " << e.message());
|
||
auto tcp_listeners_closed_before = tcp_listeners_closed_.size();
|
||
tcp_listeners_closed_.remove_if([listener] (TcpListener &t) { return &t == listener; });
|
||
auto tcp_listeners_closed_count = tcp_listeners_closed_before - tcp_listeners_closed_.size();
|
||
LOG_INFO("handleTcpAccept: async_accept: acceptor closed, removed " << tcp_listeners_closed_count << " matching connections");
|
||
return;
|
||
} else {
|
||
LOG_ERROR("handleTcpAccept: async_accept error: " << e.message());
|
||
... | ... | |
// The server is stopped by cancelling all outstanding asynchronous
|
||
// operations. Once all operations have finished the io_service::run() call
|
||
// will exit.
|
||
for (std::size_t i = 0; i < tcp_listeners_.size(); ++i)
|
||
tcp_listeners_[i].acceptor.close();
|
||
tcp_listeners_.clear();
|
||
for (auto &&tcp_listener: tcp_listeners_)
|
||
tcp_listener.acceptor.close();
|
||
tcp_listeners_closed_.splice(tcp_listeners_closed_.end(), tcp_listeners_);
|
||
#ifdef HTTP_WITH_SSL
|
||
for (std::size_t i = 0; i < ssl_listeners_.size(); ++i)
|
src/http/Server.h | ||
---|---|---|
Wt::AsioWrapper::strand accept_strand_;
|
||
/// Acceptors used to listen for incoming http connections.
|
||
std::vector<TcpListener> tcp_listeners_;
|
||
std::list<TcpListener> tcp_listeners_;
|
||
/// Acceptors that have been closed and are waiting asio acknowledgement of close
|
||
std::list<TcpListener> tcp_listeners_closed_;
|
||
#ifdef HTTP_WITH_SSL
|
||
struct SslListener {
|