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:
parent
90b00cfc66
commit
33233409a9
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user