Project

General

Profile

Bug #11302 » 0004-Track-closing-tcp-connections-to-avoid-race.patch

Bruce Toll, 02/01/2023 11:05 PM

View differences:

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 {
(2-2/8)