3636
3737#include < boost/algorithm/string/case_conv.hpp> // for to_lower()
3838#include < boost/foreach.hpp>
39- #include < boost/scoped_ptr.hpp>
4039
4140/* * Maximum size of http request (request line + headers) */
4241static const size_t MAX_HEADERS_SIZE = 8192 ;
@@ -45,16 +44,16 @@ static const size_t MAX_HEADERS_SIZE = 8192;
4544class HTTPWorkItem : public HTTPClosure
4645{
4746public:
48- HTTPWorkItem (HTTPRequest* req, const std::string &path, const HTTPRequestHandler& func):
49- req (req), path(path), func(func)
47+ HTTPWorkItem (std::unique_ptr< HTTPRequest> req, const std::string &path, const HTTPRequestHandler& func):
48+ req (std::move( req) ), path(path), func(func)
5049 {
5150 }
5251 void operator ()()
5352 {
5453 func (req.get (), path);
5554 }
5655
57- boost::scoped_ptr <HTTPRequest> req;
56+ std::unique_ptr <HTTPRequest> req;
5857
5958private:
6059 std::string path;
@@ -71,8 +70,7 @@ class WorkQueue
7170 /* * Mutex protects entire object */
7271 CWaitableCriticalSection cs;
7372 CConditionVariable cond;
74- /* XXX in C++11 we can use std::unique_ptr here and avoid manual cleanup */
75- std::deque<WorkItem*> queue;
73+ std::deque<std::unique_ptr<WorkItem>> queue;
7674 bool running;
7775 size_t maxDepth;
7876 int numThreads;
@@ -101,15 +99,11 @@ class WorkQueue
10199 numThreads(0 )
102100 {
103101 }
104- /* ( Precondition: worker threads have all stopped
102+ /* * Precondition: worker threads have all stopped
105103 * (call WaitExit)
106104 */
107105 ~WorkQueue ()
108106 {
109- while (!queue.empty ()) {
110- delete queue.front ();
111- queue.pop_front ();
112- }
113107 }
114108 /* * Enqueue a work item */
115109 bool Enqueue (WorkItem* item)
@@ -118,7 +112,7 @@ class WorkQueue
118112 if (queue.size () >= maxDepth) {
119113 return false ;
120114 }
121- queue.push_back ( item);
115+ queue.emplace_back (std::unique_ptr<WorkItem>( item) );
122116 cond.notify_one ();
123117 return true ;
124118 }
@@ -127,18 +121,17 @@ class WorkQueue
127121 {
128122 ThreadCounter count (*this );
129123 while (true ) {
130- WorkItem* i = 0 ;
124+ std::unique_ptr< WorkItem> i ;
131125 {
132126 boost::unique_lock<boost::mutex> lock (cs);
133127 while (running && queue.empty ())
134128 cond.wait (lock);
135129 if (!running)
136130 break ;
137- i = queue.front ();
131+ i = std::move ( queue.front () );
138132 queue.pop_front ();
139133 }
140134 (*i)();
141- delete i;
142135 }
143136 }
144137 /* * Interrupt and exit loops */
@@ -294,12 +287,14 @@ static void http_request_cb(struct evhttp_request* req, void* arg)
294287
295288 // Dispatch to worker thread
296289 if (i != iend) {
297- std::unique_ptr<HTTPWorkItem> item (new HTTPWorkItem (hreq. release ( ), path, i->handler ));
290+ std::unique_ptr<HTTPWorkItem> item (new HTTPWorkItem (std::move (hreq ), path, i->handler ));
298291 assert (workQueue);
299292 if (workQueue->Enqueue (item.get ()))
300293 item.release (); /* if true, queue took ownership */
301- else
294+ else {
295+ LogPrintf (" WARNING: request rejected because http work queue depth exceeded, it can be increased with the -rpcworkqueue= setting\n " );
302296 item->req ->WriteReply (HTTP_INTERNAL, " Work queue depth exceeded" );
297+ }
303298 } else {
304299 hreq->WriteReply (HTTP_NOTFOUND);
305300 }
0 commit comments