Merge #7966: http: Do a pending c++11 simplification handling 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)
This commit is contained in:
Wladimir J. van der Laan 2016-05-05 12:57:14 +02:00 committed by Alexander Block
parent 90b00cfc66
commit 33233409a9

View File

@ -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;
@ -45,8 +44,8 @@ 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()()
@ -54,7 +53,7 @@ public:
func(req.get(), path);
}
boost::scoped_ptr<HTTPRequest> req;
std::unique_ptr<HTTPRequest> req;
private:
std::string path;
@ -71,8 +70,7 @@ private:
/** 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;
@ -101,15 +99,11 @@ public:
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)
@ -118,7 +112,7 @@ public:
if (queue.size() >= maxDepth) {
return false;
}
queue.push_back(item);
queue.emplace_back(std::unique_ptr<WorkItem>(item));
cond.notify_one();
return true;
}
@ -127,18 +121,17 @@ public:
{
ThreadCounter count(*this);
while (true) {
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 */
@ -294,12 +287,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);
}