This prevents a potential race condition if control flow ends up in
ShutdownHTTPServer
before the thread gets to queue->Run()
,
deleting the work queue while workers are still going to use it.
Meant to fix #12362.
448@@ -449,6 +449,7 @@ bool UpdateHTTPServerLogging(bool enable) {
449
450 std::thread threadHTTP;
451 std::future<bool> threadResult;
452+static std::vector<std::thread> threadHTTPWorkers;
460@@ -460,8 +461,7 @@ bool StartHTTPServer()
461 threadHTTP = std::thread(std::move(task), eventBase, eventHTTP);
462
463 for (int i = 0; i < rpcThreads; i++) {
464- std::thread rpc_worker(HTTPWorkQueueRun, workQueue);
465- rpc_worker.detach();
466+ threadHTTPWorkers.emplace_back(std::thread(HTTPWorkQueueRun, workQueue));
Tested ACK 2fefa3077e69dfdbccbd010cda5627787ec92bb8 - my previous sleeps and valgrind are no longer able to find any issue here.
Would love to see @jnewbery confirm he cannot reproduce anymore as well.
This prevents a potential race condition if control flow ends up in
`ShutdownHTTPServer` before the thread gets to `queue->Run()`,
deleting the work queue while workers are still going to use it.
Meant to fix #12362.
Signed-off-by: Wladimir J. van der Laan <laanwj@gmail.com>
This function, which waits for all threads to exit, is no longer needed
now that threads are joined instead.
Signed-off-by: Wladimir J. van der Laan <laanwj@gmail.com>
486@@ -487,6 +487,10 @@ void StopHTTPServer()
487 if (workQueue) {
488 LogPrint(BCLog::HTTP, "Waiting for HTTP worker threads to exit\n");
489 workQueue->WaitExit();
139@@ -141,13 +140,6 @@ class WorkQueue
140 running = false;
141 cond.notify_all();
142 }
143- /** Wait for worker threads to exit */
144- void WaitExit()
145- {
146- std::unique_lock<std::mutex> lock(cs);
147- while (numThreads > 0)
In commit “http: Remove WaitExit from WorkQueue”
It looks like the numThreads variable is unused now, so it might be worth removing as well.
477@@ -486,7 +478,10 @@ void StopHTTPServer()
478 LogPrint(BCLog::HTTP, "Stopping HTTP server\n");
479 if (workQueue) {
480 LogPrint(BCLog::HTTP, "Waiting for HTTP worker threads to exit\n");
481- workQueue->WaitExit();
482+ for (auto& thread: g_thread_http_workers) {
483+ thread.join();
clear()
below is enough.
The HTTP worker thread counter, as well as the RAII object that was used
to maintain it, is unused now, so can be removed.
Signed-off-by: Wladimir J. van der Laan <laanwj@gmail.com>
95
96 public:
97 explicit WorkQueue(size_t _maxDepth) : running(true),
98- maxDepth(_maxDepth),
99- numThreads(0)
100+ maxDepth(_maxDepth)
456@@ -486,7 +457,10 @@ void StopHTTPServer()
457 LogPrint(BCLog::HTTP, "Stopping HTTP server\n");
458 if (workQueue) {
459 LogPrint(BCLog::HTTP, "Waiting for HTTP worker threads to exit\n");
460- workQueue->WaitExit();
461+ for (auto& thread: g_thread_http_workers) {
:
.
419@@ -449,6 +420,7 @@ bool UpdateHTTPServerLogging(bool enable) {
420
421 std::thread threadHTTP;
422 std::future<bool> threadResult;
Nice cleanup!
FWIW I wrote HTTPWorkQueue with the idea that it could likely be replaced with a 1-liner after c++11, I think there’s scope for more code removal. Out of scope for a 0.16.0 fix ofc.
laanwj
ryanofsky
TheBlueMatt
jnewbery
promag
sipa
dcousens
meshcollider
Labels
Bug
RPC/REST/ZMQ
Milestone
0.16.0