diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2016-05-05 12:57:14 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2016-05-05 12:57:31 +0200 |
commit | d51618e481abc15155ef125ccf91c8be4e673dea (patch) | |
tree | 5e46022bd85feac1f648b10694ec1250caa328bc | |
parent | 06303533230fafe1346b8c2e8ef3bc1f7f2885a3 (diff) | |
parent | f0188f9178a22fd493ed228c008d4cc25ac2952d (diff) |
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)
-rw-r--r-- | src/httpserver.cpp | 29 |
1 files changed, 12 insertions, 17 deletions
diff --git a/src/httpserver.cpp b/src/httpserver.cpp index a98eff7c16..812940eaf9 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -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 (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 */ @@ -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); } |