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