Skip to content

Commit 9ae731d

Browse files
httpserver: drop boost
1 parent e65aff6 commit 9ae731d

File tree

2 files changed

+34
-36
lines changed

2 files changed

+34
-36
lines changed

src/httpserver.cpp

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <sys/types.h>
2121
#include <sys/stat.h>
2222
#include <signal.h>
23+
#include <future>
2324

2425
#include <event2/event.h>
2526
#include <event2/http.h>
@@ -35,9 +36,6 @@
3536
#endif
3637
#endif
3738

38-
#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
39-
#include <boost/foreach.hpp>
40-
4139
/** Maximum size of http request (request line + headers) */
4240
static const size_t MAX_HEADERS_SIZE = 8192;
4341

@@ -69,8 +67,8 @@ class WorkQueue
6967
{
7068
private:
7169
/** Mutex protects entire object */
72-
CWaitableCriticalSection cs;
73-
CConditionVariable cond;
70+
std::mutex cs;
71+
std::condition_variable cond;
7472
std::deque<std::unique_ptr<WorkItem>> queue;
7573
bool running;
7674
size_t maxDepth;
@@ -83,12 +81,12 @@ class WorkQueue
8381
WorkQueue &wq;
8482
ThreadCounter(WorkQueue &w): wq(w)
8583
{
86-
boost::lock_guard<boost::mutex> lock(wq.cs);
84+
std::lock_guard<std::mutex> lock(wq.cs);
8785
wq.numThreads += 1;
8886
}
8987
~ThreadCounter()
9088
{
91-
boost::lock_guard<boost::mutex> lock(wq.cs);
89+
std::lock_guard<std::mutex> lock(wq.cs);
9290
wq.numThreads -= 1;
9391
wq.cond.notify_all();
9492
}
@@ -109,7 +107,7 @@ class WorkQueue
109107
/** Enqueue a work item */
110108
bool Enqueue(WorkItem* item)
111109
{
112-
boost::unique_lock<boost::mutex> lock(cs);
110+
std::unique_lock<std::mutex> lock(cs);
113111
if (queue.size() >= maxDepth) {
114112
return false;
115113
}
@@ -124,7 +122,7 @@ class WorkQueue
124122
while (true) {
125123
std::unique_ptr<WorkItem> i;
126124
{
127-
boost::unique_lock<boost::mutex> lock(cs);
125+
std::unique_lock<std::mutex> lock(cs);
128126
while (running && queue.empty())
129127
cond.wait(lock);
130128
if (!running)
@@ -138,14 +136,14 @@ class WorkQueue
138136
/** Interrupt and exit loops */
139137
void Interrupt()
140138
{
141-
boost::unique_lock<boost::mutex> lock(cs);
139+
std::unique_lock<std::mutex> lock(cs);
142140
running = false;
143141
cond.notify_all();
144142
}
145143
/** Wait for worker threads to exit */
146144
void WaitExit()
147145
{
148-
boost::unique_lock<boost::mutex> lock(cs);
146+
std::unique_lock<std::mutex> lock(cs);
149147
while (numThreads > 0){
150148
cond.wait(lock);
151149
}
@@ -154,7 +152,7 @@ class WorkQueue
154152
/** Return current depth of queue */
155153
size_t Depth()
156154
{
157-
boost::unique_lock<boost::mutex> lock(cs);
155+
std::unique_lock<std::mutex> lock(cs);
158156
return queue.size();
159157
}
160158
};
@@ -191,7 +189,7 @@ static bool ClientAllowed(const CNetAddr& netaddr)
191189
{
192190
if (!netaddr.IsValid())
193191
return false;
194-
BOOST_FOREACH (const CSubNet& subnet, rpc_allow_subnets)
192+
for(const CSubNet& subnet : rpc_allow_subnets)
195193
if (subnet.Match(netaddr))
196194
return true;
197195
return false;
@@ -209,7 +207,7 @@ static bool InitHTTPAllowList()
209207
rpc_allow_subnets.push_back(CSubNet(localv6)); // always allow IPv6 localhost
210208
if (mapMultiArgs.count("-rpcallowip")) {
211209
const std::vector<std::string>& vAllow = mapMultiArgs["-rpcallowip"];
212-
BOOST_FOREACH (std::string strAllow, vAllow) {
210+
for (std::string strAllow : vAllow) {
213211
CSubNet subnet;
214212
LookupSubNet(strAllow.c_str(), subnet);
215213
if (!subnet.IsValid()) {
@@ -222,7 +220,7 @@ static bool InitHTTPAllowList()
222220
}
223221
}
224222
std::string strAllowed;
225-
BOOST_FOREACH (const CSubNet& subnet, rpc_allow_subnets)
223+
for (const CSubNet& subnet : rpc_allow_subnets)
226224
strAllowed += subnet.ToString() + " ";
227225
LogPrint("http", "Allowing HTTP connections from: %s\n", strAllowed);
228226
return true;
@@ -309,13 +307,14 @@ static void http_reject_request_cb(struct evhttp_request* req, void*)
309307
}
310308

311309
/** Event dispatcher thread */
312-
static void ThreadHTTP(struct event_base* base, struct evhttp* http)
310+
static bool ThreadHTTP(struct event_base* base, struct evhttp* http)
313311
{
314312
RenameThread("dynamic-http");
315313
LogPrint("http", "Entering http event loop\n");
316314
event_base_dispatch(base);
317315
// Event loop will be interrupted by InterruptHTTPServer()
318316
LogPrint("http", "Exited http event loop\n");
317+
return event_base_got_break(base) == 0;
319318
}
320319

321320
/** Bind HTTP server to specified addresses */
@@ -444,17 +443,22 @@ bool InitHTTPServer()
444443
return true;
445444
}
446445

447-
boost::thread threadHTTP;
446+
std::thread threadHTTP;
447+
std::future<bool> threadResult;
448448

449449
bool StartHTTPServer()
450450
{
451451
LogPrint("http", "Starting HTTP server\n");
452452
int rpcThreads = std::max((long)GetArg("-rpcthreads", DEFAULT_HTTP_THREADS), 1L);
453453
LogPrintf("HTTP: starting %d worker threads\n", rpcThreads);
454-
threadHTTP = boost::thread(boost::bind(&ThreadHTTP, eventBase, eventHTTP));
454+
std::packaged_task<bool(event_base*, evhttp*)> task(ThreadHTTP);
455+
threadResult = task.get_future();
456+
threadHTTP = std::thread(std::move(task), eventBase, eventHTTP);
455457

456-
for (int i = 0; i < rpcThreads; i++)
457-
boost::thread(boost::bind(&HTTPWorkQueueRun, workQueue));
458+
for (int i = 0; i < rpcThreads; i++) {
459+
std::thread rpc_worker(HTTPWorkQueueRun, workQueue);
460+
rpc_worker.detach();
461+
}
458462
return true;
459463
}
460464

@@ -463,7 +467,7 @@ void InterruptHTTPServer()
463467
LogPrint("http", "Interrupting HTTP server\n");
464468
if (eventHTTP) {
465469
// Unlisten sockets
466-
BOOST_FOREACH (evhttp_bound_socket *socket, boundSockets) {
470+
for (evhttp_bound_socket *socket : boundSockets) {
467471
evhttp_del_accept_socket(eventHTTP, socket);
468472
}
469473
// Reject requests on current connections
@@ -494,16 +498,11 @@ void StopHTTPServer()
494498
// master that appears to be solved, so in the future that solution
495499
// could be used again (if desirable).
496500
// (see discussion in https://github.com/bitcoin/bitcoin/pull/6990)
497-
#if BOOST_VERSION >= 105000
498-
if (!threadHTTP.try_join_for(boost::chrono::milliseconds(2000))) {
499-
#else
500-
if (!threadHTTP.timed_join(boost::posix_time::milliseconds(2000))) {
501-
#endif
502-
501+
+ if (threadResult.valid() && threadResult.wait_for(std::chrono::milliseconds(2000)) == std::future_status::timeout) {
503502
LogPrintf("HTTP event loop did not exit within allotted time, sending loopbreak\n");
504503
event_base_loopbreak(eventBase);
505-
threadHTTP.join();
506504
}
505+
threadHTTP.join();
507506
}
508507
if (eventHTTP) {
509508
evhttp_free(eventHTTP);
@@ -530,7 +529,7 @@ static void httpevent_callback_fn(evutil_socket_t, short, void* data)
530529
delete self;
531530
}
532531

533-
HTTPEvent::HTTPEvent(struct event_base* base, bool deleteWhenTriggered, const boost::function<void(void)>& handler):
532+
HTTPEvent::HTTPEvent(struct event_base* base, bool deleteWhenTriggered, const std::function<void(void)>& handler):
534533
deleteWhenTriggered(deleteWhenTriggered), handler(handler)
535534
{
536535
ev = event_new(base, -1, 0, httpevent_callback_fn, this);
@@ -612,7 +611,7 @@ void HTTPRequest::WriteReply(int nStatus, const std::string& strReply)
612611
assert(evb);
613612
evbuffer_add(evb, strReply.data(), strReply.size());
614613
HTTPEvent* ev = new HTTPEvent(eventBase, true,
615-
boost::bind(evhttp_send_reply, req, nStatus, (const char*)NULL, (struct evbuffer *)NULL));
614+
std::bind(evhttp_send_reply, req, nStatus, (const char*)NULL, (struct evbuffer *)NULL));
616615
ev->trigger(0);
617616
replySent = true;
618617
req = 0; // transferred back to main thread

src/httpserver.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@
88

99
#include <string>
1010
#include <stdint.h>
11-
#include <boost/thread.hpp>
12-
#include <boost/scoped_ptr.hpp>
13-
#include <boost/function.hpp>
11+
#include <functional>
12+
1413

1514
static const int DEFAULT_HTTP_THREADS=4;
1615
static const int DEFAULT_HTTP_WORKQUEUE=16;
@@ -36,7 +35,7 @@ void InterruptHTTPServer();
3635
void StopHTTPServer();
3736

3837
/** Handler for requests to a certain HTTP path */
39-
typedef boost::function<void(HTTPRequest* req, const std::string &)> HTTPRequestHandler;
38+
typedef std::function<void(HTTPRequest* req, const std::string &)> HTTPRequestHandler;
4039
/** Register handler for prefix.
4140
* If multiple handlers match a prefix, the first-registered one will
4241
* be invoked.
@@ -133,7 +132,7 @@ class HTTPEvent
133132
* deleteWhenTriggered deletes this event object after the event is triggered (and the handler called)
134133
* handler is the handler to call when the event is triggered.
135134
*/
136-
HTTPEvent(struct event_base* base, bool deleteWhenTriggered, const boost::function<void(void)>& handler);
135+
HTTPEvent(struct event_base* base, bool deleteWhenTriggered, const std::function<void(void)>& handler);
137136
~HTTPEvent();
138137

139138
/** Trigger the event. If tv is 0, trigger it immediately. Otherwise trigger it after
@@ -142,7 +141,7 @@ class HTTPEvent
142141
void trigger(struct timeval* tv);
143142

144143
bool deleteWhenTriggered;
145-
boost::function<void(void)> handler;
144+
std::function<void(void)> handler;
146145
private:
147146
struct event* ev;
148147
};

0 commit comments

Comments
 (0)