36
36
37
37
#include < boost/algorithm/string/case_conv.hpp> // for to_lower()
38
38
#include < boost/foreach.hpp>
39
- #include < boost/scoped_ptr.hpp>
40
39
41
40
/* * Maximum size of http request (request line + headers) */
42
41
static const size_t MAX_HEADERS_SIZE = 8192 ;
@@ -45,16 +44,16 @@ static const size_t MAX_HEADERS_SIZE = 8192;
45
44
class HTTPWorkItem : public HTTPClosure
46
45
{
47
46
public:
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)
50
49
{
51
50
}
52
51
void operator ()()
53
52
{
54
53
func (req.get (), path);
55
54
}
56
55
57
- boost::scoped_ptr <HTTPRequest> req;
56
+ std::unique_ptr <HTTPRequest> req;
58
57
59
58
private:
60
59
std::string path;
@@ -71,8 +70,7 @@ class WorkQueue
71
70
/* * Mutex protects entire object */
72
71
CWaitableCriticalSection cs;
73
72
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;
76
74
bool running;
77
75
size_t maxDepth;
78
76
int numThreads;
@@ -101,15 +99,11 @@ class WorkQueue
101
99
numThreads(0 )
102
100
{
103
101
}
104
- /* ( Precondition: worker threads have all stopped
102
+ /* * Precondition: worker threads have all stopped
105
103
* (call WaitExit)
106
104
*/
107
105
~WorkQueue ()
108
106
{
109
- while (!queue.empty ()) {
110
- delete queue.front ();
111
- queue.pop_front ();
112
- }
113
107
}
114
108
/* * Enqueue a work item */
115
109
bool Enqueue (WorkItem* item)
@@ -118,7 +112,7 @@ class WorkQueue
118
112
if (queue.size () >= maxDepth) {
119
113
return false ;
120
114
}
121
- queue.push_back ( item);
115
+ queue.emplace_back (std::unique_ptr<WorkItem>( item) );
122
116
cond.notify_one ();
123
117
return true ;
124
118
}
@@ -127,18 +121,17 @@ class WorkQueue
127
121
{
128
122
ThreadCounter count (*this );
129
123
while (running) {
130
- WorkItem* i = 0 ;
124
+ std::unique_ptr< WorkItem> i ;
131
125
{
132
126
boost::unique_lock<boost::mutex> lock (cs);
133
127
while (running && queue.empty ())
134
128
cond.wait (lock);
135
129
if (!running)
136
130
break ;
137
- i = queue.front ();
131
+ i = std::move ( queue.front () );
138
132
queue.pop_front ();
139
133
}
140
134
(*i)();
141
- delete i;
142
135
}
143
136
}
144
137
/* * Interrupt and exit loops */
@@ -288,12 +281,14 @@ static void http_request_cb(struct evhttp_request* req, void* arg)
288
281
289
282
// Dispatch to worker thread
290
283
if (i != iend) {
291
- std::unique_ptr<HTTPWorkItem> item (new HTTPWorkItem (hreq. release ( ), path, i->handler ));
284
+ std::unique_ptr<HTTPWorkItem> item (new HTTPWorkItem (std::move (hreq ), path, i->handler ));
292
285
assert (workQueue);
293
286
if (workQueue->Enqueue (item.get ()))
294
287
item.release (); /* if true, queue took ownership */
295
- else
288
+ else {
289
+ LogPrintf (" WARNING: request rejected because http work queue depth exceeded, it can be increased with the -rpcworkqueue= setting\n " );
296
290
item->req ->WriteReply (HTTP_INTERNAL, " Work queue depth exceeded" );
291
+ }
297
292
} else {
298
293
hreq->WriteReply (HTTP_NOTFOUND);
299
294
}
0 commit comments