@@ -438,15 +438,17 @@ bool InitHTTPServer()
438438 return true ;
439439}
440440
441- bool StartHTTPServer (boost::thread_group& threadGroup)
441+ boost::thread threadHTTP;
442+
443+ bool StartHTTPServer ()
442444{
443445 LogPrint (" http" , " Starting HTTP server\n " );
444446 int rpcThreads = std::max ((long )GetArg (" -rpcthreads" , DEFAULT_HTTP_THREADS), 1L );
445447 LogPrintf (" HTTP: starting %d worker threads\n " , rpcThreads);
446- threadGroup. create_thread (boost::bind (&ThreadHTTP, eventBase, eventHTTP));
448+ threadHTTP = boost::thread (boost::bind (&ThreadHTTP, eventBase, eventHTTP));
447449
448450 for (int i = 0 ; i < rpcThreads; i++)
449- threadGroup. create_thread (boost::bind (&HTTPWorkQueueRun, workQueue));
451+ boost::thread (boost::bind (&HTTPWorkQueueRun, workQueue));
450452 return true ;
451453}
452454
@@ -461,13 +463,6 @@ void InterruptHTTPServer()
461463 // Reject requests on current connections
462464 evhttp_set_gencb (eventHTTP, http_reject_request_cb, NULL );
463465 }
464- if (eventBase) {
465- // Force-exit event loop after predefined time
466- struct timeval tv;
467- tv.tv_sec = 10 ;
468- tv.tv_usec = 0 ;
469- event_base_loopexit (eventBase, &tv);
470- }
471466 if (workQueue)
472467 workQueue->Interrupt ();
473468}
@@ -480,6 +475,20 @@ void StopHTTPServer()
480475 workQueue->WaitExit ();
481476 delete workQueue;
482477 }
478+ if (eventBase) {
479+ LogPrint (" http" , " Waiting for HTTP event thread to exit\n " );
480+ // Give event loop a few seconds to exit (to send back last RPC responses), then break it
481+ // Before this was solved with event_base_loopexit, but that didn't work as expected in
482+ // at least libevent 2.0.21 and always introduced a delay. In libevent
483+ // master that appears to be solved, so in the future that solution
484+ // could be used again (if desirable).
485+ // (see discussion in https://github.com/bitcoin/bitcoin/pull/6990)
486+ if (!threadHTTP.try_join_for (boost::chrono::milliseconds (2000 ))) {
487+ LogPrintf (" HTTP event loop did not exit within allotted time, sending loopbreak\n " );
488+ event_base_loopbreak (eventBase);
489+ threadHTTP.join ();
490+ }
491+ }
483492 if (eventHTTP) {
484493 evhttp_free (eventHTTP);
485494 eventHTTP = 0 ;
@@ -488,6 +497,7 @@ void StopHTTPServer()
488497 event_base_free (eventBase);
489498 eventBase = 0 ;
490499 }
500+ LogPrint (" http" , " Stopped HTTP server\n " );
491501}
492502
493503struct event_base * EventBase ()
0 commit comments