|
|
@ -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); |
|
|
|