httpserver: use a future rather than relying on boost's try_join_for

This commit is contained in:
Cory Fields 2016-07-28 17:52:51 -04:00
parent 133c727cc4
commit 755aa05174

View File

@ -19,6 +19,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <future>
#include <event2/event.h>
#include <event2/http.h>
@ -302,13 +303,14 @@ static void http_reject_request_cb(struct evhttp_request* req, void*)
}
/** Event dispatcher thread */
static void ThreadHTTP(struct event_base* base, struct evhttp* http)
static bool ThreadHTTP(struct event_base* base, struct evhttp* http)
{
RenameThread("bitcoin-http");
LogPrint("http", "Entering http event loop\n");
event_base_dispatch(base);
// Event loop will be interrupted by InterruptHTTPServer()
LogPrint("http", "Exited http event loop\n");
return event_base_got_break(base) == 0;
}
/** Bind HTTP server to specified addresses */
@ -438,13 +440,16 @@ bool InitHTTPServer()
}
boost::thread threadHTTP;
std::future<bool> threadResult;
bool StartHTTPServer()
{
LogPrint("http", "Starting HTTP server\n");
int rpcThreads = std::max((long)GetArg("-rpcthreads", DEFAULT_HTTP_THREADS), 1L);
LogPrintf("HTTP: starting %d worker threads\n", rpcThreads);
threadHTTP = boost::thread(boost::bind(&ThreadHTTP, eventBase, eventHTTP));
std::packaged_task<bool(event_base*, evhttp*)> task(ThreadHTTP);
threadResult = task.get_future();
threadHTTP = boost::thread(std::bind(std::move(task), eventBase, eventHTTP));
for (int i = 0; i < rpcThreads; i++)
boost::thread(boost::bind(&HTTPWorkQueueRun, workQueue));
@ -482,15 +487,11 @@ void StopHTTPServer()
// 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 BOOST_VERSION >= 105000
if (!threadHTTP.try_join_for(boost::chrono::milliseconds(2000))) {
#else
if (!threadHTTP.timed_join(boost::posix_time::milliseconds(2000))) {
#endif
if (threadResult.valid() && threadResult.wait_for(std::chrono::milliseconds(2000)) == std::future_status::timeout) {
LogPrintf("HTTP event loop did not exit within allotted time, sending loopbreak\n");
event_base_loopbreak(eventBase);
threadHTTP.join();
}
threadHTTP.join();
}
if (eventHTTP) {
evhttp_free(eventHTTP);