From 757de96db5628cfbf0f2d0dbaaa135da77440bd9 Mon Sep 17 00:00:00 2001 From: Hodlinator <172445034+hodlinator@users.noreply.github.com> Date: Fri, 21 Feb 2025 14:31:36 +0100 Subject: [PATCH] http: Ensure eventHTTP is always freed There is a race between ThreadHTTP exiting and our queuing of the freeing-event (event_base_once). Additional free was useful in 709 of 962 runs. --- src/httpserver.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index bc65453dbda..a3a6a8bea62 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -546,16 +546,25 @@ void StopHTTPServer() // Schedule a callback to call evhttp_free in the event base thread, as // otherwise eventHTTP often keeps internal events alive, meaning // aforementioned thread would never run out of events and exit. - event_base_once(eventBase, -1, EV_TIMEOUT, [](evutil_socket_t, short, void*) { + if (event_base_once(eventBase, -1, EV_TIMEOUT, [](evutil_socket_t, short, void*) { evhttp_free(eventHTTP); eventHTTP = nullptr; - }, nullptr, nullptr); + }, nullptr, nullptr) != 0) { + LogDebug(BCLog::HTTP, "event_base_once failed"); + } } if (eventBase) { LogDebug(BCLog::HTTP, "Waiting for HTTP event thread to exit\n"); if (g_thread_http.joinable()) g_thread_http.join(); + if (eventHTTP) { + LogDebug(BCLog::HTTP, "Freeing eventHTTP-event was not picked up by ThreadHTTP before it exited."); + evhttp_free(eventHTTP); + eventHTTP = nullptr; + } event_base_free(eventBase); eventBase = nullptr; + } else { + Assume(!g_thread_http.joinable()); } g_work_queue.reset(); LogDebug(BCLog::HTTP, "Stopped HTTP server\n");