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 {
|
||