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/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <signal.h> #include <signal.h>
#include <future>
#include <event2/event.h> #include <event2/event.h>
#include <event2/http.h> #include <event2/http.h>
@ -302,13 +303,14 @@ static void http_reject_request_cb(struct evhttp_request* req, void*)
} }
/** Event dispatcher thread */ /** 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"); RenameThread("bitcoin-http");
LogPrint("http", "Entering http event loop\n"); LogPrint("http", "Entering http event loop\n");
event_base_dispatch(base); event_base_dispatch(base);
// Event loop will be interrupted by InterruptHTTPServer() // Event loop will be interrupted by InterruptHTTPServer()
LogPrint("http", "Exited http event loop\n"); LogPrint("http", "Exited http event loop\n");
return event_base_got_break(base) == 0;
} }
/** Bind HTTP server to specified addresses */ /** Bind HTTP server to specified addresses */
@ -438,13 +440,16 @@ bool InitHTTPServer()
} }
boost::thread threadHTTP; boost::thread threadHTTP;
std::future<bool> threadResult;
bool StartHTTPServer() 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);
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++) for (int i = 0; i < rpcThreads; i++)
boost::thread(boost::bind(&HTTPWorkQueueRun, workQueue)); boost::thread(boost::bind(&HTTPWorkQueueRun, workQueue));
@ -482,15 +487,11 @@ void StopHTTPServer()
// master that appears to be solved, so in the future that solution // master that appears to be solved, so in the future that solution
// could be used again (if desirable). // could be used again (if desirable).
// (see discussion in https://github.com/bitcoin/bitcoin/pull/6990) // (see discussion in https://github.com/bitcoin/bitcoin/pull/6990)
#if BOOST_VERSION >= 105000 if (threadResult.valid() && threadResult.wait_for(std::chrono::milliseconds(2000)) == std::future_status::timeout) {
if (!threadHTTP.try_join_for(boost::chrono::milliseconds(2000))) {
#else
if (!threadHTTP.timed_join(boost::posix_time::milliseconds(2000))) {
#endif
LogPrintf("HTTP event loop did not exit within allotted time, sending loopbreak\n"); LogPrintf("HTTP event loop did not exit within allotted time, sending loopbreak\n");
event_base_loopbreak(eventBase); event_base_loopbreak(eventBase);
threadHTTP.join();
} }
threadHTTP.join();
} }
if (eventHTTP) { if (eventHTTP) {
evhttp_free(eventHTTP); evhttp_free(eventHTTP);