mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-17 21:32:00 +01:00
http: Abort with clear error instead of hanging forever
Could happen when connection doesn't complete for some reason. Output early warning to give clue about what's up. Prior check+log message before even starting to wait was a bit too eager to hint at something being wrong.
This commit is contained in:
parent
757de96db5
commit
a00dfd2046
@ -197,10 +197,10 @@ public:
|
||||
return WITH_LOCK(m_mutex, return m_tracker.size());
|
||||
}
|
||||
//! Wait until there are no more connections with active requests in the tracker
|
||||
void WaitUntilEmpty() const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
|
||||
void WaitUntilEmpty(std::chrono::seconds timeout) const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
|
||||
{
|
||||
WAIT_LOCK(m_mutex, lock);
|
||||
m_cv.wait(lock, [this]() EXCLUSIVE_LOCKS_REQUIRED(m_mutex) { return m_tracker.empty(); });
|
||||
m_cv.wait_for(lock, timeout, [this]() EXCLUSIVE_LOCKS_REQUIRED(m_mutex) { return m_tracker.empty(); });
|
||||
}
|
||||
};
|
||||
//! Track active requests
|
||||
@ -536,11 +536,19 @@ void StopHTTPServer()
|
||||
evhttp_del_accept_socket(eventHTTP, socket);
|
||||
}
|
||||
boundSockets.clear();
|
||||
{
|
||||
if (const auto n_connections{g_requests.CountActiveConnections()}; n_connections != 0) {
|
||||
LogDebug(BCLog::HTTP, "Waiting for %d connections to stop HTTP server\n", n_connections);
|
||||
// Give clients time to close down TCP connections from their side before we
|
||||
// free eventHTTP, this avoids issues like RemoteDisconnected exceptions in
|
||||
// the test framework.
|
||||
g_requests.WaitUntilEmpty(/*timeout=*/30s);
|
||||
if (auto connections{g_requests.CountActiveConnections()}) {
|
||||
LogWarning("%d remaining HTTP connection(s) after 30s timeout, waiting for longer.", connections);
|
||||
g_requests.WaitUntilEmpty(/*timeout=*/10min);
|
||||
if ((connections = g_requests.CountActiveConnections())) {
|
||||
LogError("%d remaining HTTP connection(s) after long timeout. "
|
||||
"Aborting to avoid potential use-after-frees from "
|
||||
"connections still running after freeing eventHTTP.", connections);
|
||||
std::abort();
|
||||
}
|
||||
g_requests.WaitUntilEmpty();
|
||||
}
|
||||
if (eventHTTP) {
|
||||
// Schedule a callback to call evhttp_free in the event base thread, as
|
||||
|
Loading…
x
Reference in New Issue
Block a user