Skip to content

Commit

Permalink
Merge bitcoin#7966: http: Do a pending c++11 simplification handling …
Browse files Browse the repository at this point in the history
…work items

f0188f9 http: use std::move to move HTTPRequest into HTTPWorkItem (Wladimir J. van der Laan)
37b2137 http: Change boost::scoped_ptr to std::unique_ptr in HTTPRequest (Wladimir J. van der Laan)
f97b410 http: Add log message when work queue is full (Wladimir J. van der Laan)
091d6e0 http: Do a pending c++11 simplification (Wladimir J. van der Laan)
  • Loading branch information
laanwj committed May 5, 2016
2 parents 0630353 + f0188f9 commit d51618e
Showing 1 changed file with 12 additions and 17 deletions.
29 changes: 12 additions & 17 deletions src/httpserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@

#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
#include <boost/foreach.hpp>
#include <boost/scoped_ptr.hpp>

/** Maximum size of http request (request line + headers) */
static const size_t MAX_HEADERS_SIZE = 8192;
Expand All @@ -45,16 +44,16 @@ static const size_t MAX_HEADERS_SIZE = 8192;
class HTTPWorkItem : public HTTPClosure
{
public:
HTTPWorkItem(HTTPRequest* req, const std::string &path, const HTTPRequestHandler& func):
req(req), path(path), func(func)
HTTPWorkItem(std::unique_ptr<HTTPRequest> req, const std::string &path, const HTTPRequestHandler& func):
req(std::move(req)), path(path), func(func)
{
}
void operator()()
{
func(req.get(), path);
}

boost::scoped_ptr<HTTPRequest> req;
std::unique_ptr<HTTPRequest> req;

private:
std::string path;
Expand All @@ -71,8 +70,7 @@ class WorkQueue
/** Mutex protects entire object */
CWaitableCriticalSection cs;
CConditionVariable cond;
/* XXX in C++11 we can use std::unique_ptr here and avoid manual cleanup */
std::deque<WorkItem*> queue;
std::deque<std::unique_ptr<WorkItem>> queue;
bool running;
size_t maxDepth;
int numThreads;
Expand Down Expand Up @@ -101,15 +99,11 @@ class WorkQueue
numThreads(0)
{
}
/*( Precondition: worker threads have all stopped
/** Precondition: worker threads have all stopped
* (call WaitExit)
*/
~WorkQueue()
{
while (!queue.empty()) {
delete queue.front();
queue.pop_front();
}
}
/** Enqueue a work item */
bool Enqueue(WorkItem* item)
Expand All @@ -118,7 +112,7 @@ class WorkQueue
if (queue.size() >= maxDepth) {
return false;
}
queue.push_back(item);
queue.emplace_back(std::unique_ptr<WorkItem>(item));
cond.notify_one();
return true;
}
Expand All @@ -127,18 +121,17 @@ class WorkQueue
{
ThreadCounter count(*this);
while (running) {
WorkItem* i = 0;
std::unique_ptr<WorkItem> i;
{
boost::unique_lock<boost::mutex> lock(cs);
while (running && queue.empty())
cond.wait(lock);
if (!running)
break;
i = queue.front();
i = std::move(queue.front());
queue.pop_front();
}
(*i)();
delete i;
}
}
/** Interrupt and exit loops */
Expand Down Expand Up @@ -288,12 +281,14 @@ static void http_request_cb(struct evhttp_request* req, void* arg)

// Dispatch to worker thread
if (i != iend) {
std::unique_ptr<HTTPWorkItem> item(new HTTPWorkItem(hreq.release(), path, i->handler));
std::unique_ptr<HTTPWorkItem> item(new HTTPWorkItem(std::move(hreq), path, i->handler));
assert(workQueue);
if (workQueue->Enqueue(item.get()))
item.release(); /* if true, queue took ownership */
else
else {
LogPrintf("WARNING: request rejected because http work queue depth exceeded, it can be increased with the -rpcworkqueue= setting\n");
item->req->WriteReply(HTTP_INTERNAL, "Work queue depth exceeded");
}
} else {
hreq->WriteReply(HTTP_NOTFOUND);
}
Expand Down

0 comments on commit d51618e

Please sign in to comment.