Browse Source

Merge pull request #6990

a264c32 http: speed up shutdown (Wladimir J. van der Laan)
0.13
Gregory Maxwell 9 years ago
parent
commit
dbd2c135dd
No known key found for this signature in database
GPG Key ID: EAB5AF94D9E9ABE7
  1. 30
      src/httpserver.cpp
  2. 2
      src/httpserver.h
  3. 2
      src/init.cpp

30
src/httpserver.cpp

@ -438,15 +438,17 @@ bool InitHTTPServer()
return true; return true;
} }
bool StartHTTPServer(boost::thread_group& threadGroup) boost::thread threadHTTP;
bool StartHTTPServer()
{ {
LogPrint("http", "Starting HTTP server\n"); LogPrint("http", "Starting HTTP server\n");
int rpcThreads = std::max((long)GetArg("-rpcthreads", DEFAULT_HTTP_THREADS), 1L); int rpcThreads = std::max((long)GetArg("-rpcthreads", DEFAULT_HTTP_THREADS), 1L);
LogPrintf("HTTP: starting %d worker threads\n", rpcThreads); LogPrintf("HTTP: starting %d worker threads\n", rpcThreads);
threadGroup.create_thread(boost::bind(&ThreadHTTP, eventBase, eventHTTP)); threadHTTP = boost::thread(boost::bind(&ThreadHTTP, eventBase, eventHTTP));
for (int i = 0; i < rpcThreads; i++) for (int i = 0; i < rpcThreads; i++)
threadGroup.create_thread(boost::bind(&HTTPWorkQueueRun, workQueue)); boost::thread(boost::bind(&HTTPWorkQueueRun, workQueue));
return true; return true;
} }
@ -461,13 +463,6 @@ void InterruptHTTPServer()
// Reject requests on current connections // Reject requests on current connections
evhttp_set_gencb(eventHTTP, http_reject_request_cb, NULL); evhttp_set_gencb(eventHTTP, http_reject_request_cb, NULL);
} }
if (eventBase) {
// Force-exit event loop after predefined time
struct timeval tv;
tv.tv_sec = 10;
tv.tv_usec = 0;
event_base_loopexit(eventBase, &tv);
}
if (workQueue) if (workQueue)
workQueue->Interrupt(); workQueue->Interrupt();
} }
@ -480,6 +475,20 @@ void StopHTTPServer()
workQueue->WaitExit(); workQueue->WaitExit();
delete workQueue; delete workQueue;
} }
if (eventBase) {
LogPrint("http", "Waiting for HTTP event thread to exit\n");
// Give event loop a few seconds to exit (to send back last RPC responses), then break it
// Before this was solved with event_base_loopexit, but that didn't work as expected in
// at least libevent 2.0.21 and always introduced a delay. In libevent
// master that appears to be solved, so in the future that solution
// could be used again (if desirable).
// (see discussion in https://github.com/bitcoin/bitcoin/pull/6990)
if (!threadHTTP.try_join_for(boost::chrono::milliseconds(2000))) {
LogPrintf("HTTP event loop did not exit within allotted time, sending loopbreak\n");
event_base_loopbreak(eventBase);
threadHTTP.join();
}
}
if (eventHTTP) { if (eventHTTP) {
evhttp_free(eventHTTP); evhttp_free(eventHTTP);
eventHTTP = 0; eventHTTP = 0;
@ -488,6 +497,7 @@ void StopHTTPServer()
event_base_free(eventBase); event_base_free(eventBase);
eventBase = 0; eventBase = 0;
} }
LogPrint("http", "Stopped HTTP server\n");
} }
struct event_base* EventBase() struct event_base* EventBase()

2
src/httpserver.h

@ -28,7 +28,7 @@ bool InitHTTPServer();
* This is separate from InitHTTPServer to give users race-condition-free time * This is separate from InitHTTPServer to give users race-condition-free time
* to register their handlers between InitHTTPServer and StartHTTPServer. * to register their handlers between InitHTTPServer and StartHTTPServer.
*/ */
bool StartHTTPServer(boost::thread_group& threadGroup); bool StartHTTPServer();
/** Interrupt HTTP server threads */ /** Interrupt HTTP server threads */
void InterruptHTTPServer(); void InterruptHTTPServer();
/** Stop HTTP server */ /** Stop HTTP server */

2
src/init.cpp

@ -668,7 +668,7 @@ bool AppInitServers(boost::thread_group& threadGroup)
return false; return false;
if (GetBoolArg("-rest", false) && !StartREST()) if (GetBoolArg("-rest", false) && !StartREST())
return false; return false;
if (!StartHTTPServer(threadGroup)) if (!StartHTTPServer())
return false; return false;
return true; return true;
} }

Loading…
Cancel
Save