@@ -311,6 +311,34 @@ struct ci {
311
311
}
312
312
};
313
313
314
+ // This is based on
315
+ // "http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4189".
316
+
317
+ template <typename EF> struct scope_exit {
318
+ explicit scope_exit (EF &&f)
319
+ : exit_function(std::move(f)), execute_on_destruction{true } {}
320
+
321
+ scope_exit (scope_exit &&rhs)
322
+ : exit_function(std::move(rhs.exit_function)),
323
+ execute_on_destruction{rhs.execute_on_destruction } {
324
+ rhs.release ();
325
+ }
326
+
327
+ ~scope_exit () {
328
+ if (execute_on_destruction) { this ->exit_function (); }
329
+ }
330
+
331
+ void release () { this ->execute_on_destruction = false ; }
332
+
333
+ private:
334
+ scope_exit (const scope_exit &) = delete ;
335
+ void operator =(const scope_exit &) = delete ;
336
+ scope_exit &operator =(scope_exit &&) = delete ;
337
+
338
+ EF exit_function;
339
+ bool execute_on_destruction;
340
+ };
341
+
314
342
} // namespace detail
315
343
316
344
using Headers = std::multimap<std::string, std::string, detail::ci>;
@@ -4785,13 +4813,14 @@ inline MultipartFormData Request::get_file_value(const std::string &key) const {
4785
4813
return MultipartFormData ();
4786
4814
}
4787
4815
4788
- inline std::vector<MultipartFormData> Request::get_file_values (const std::string &key) const {
4789
- std::vector<MultipartFormData> values;
4790
- auto rng = files.equal_range (key);
4791
- for (auto it = rng.first ; it != rng.second ; it++) {
4792
- values.push_back (it->second );
4793
- }
4794
- return values;
4816
+ inline std::vector<MultipartFormData>
4817
+ Request::get_file_values (const std::string &key) const {
4818
+ std::vector<MultipartFormData> values;
4819
+ auto rng = files.equal_range (key);
4820
+ for (auto it = rng.first ; it != rng.second ; it++) {
4821
+ values.push_back (it->second );
4822
+ }
4823
+ return values;
4795
4824
}
4796
4825
4797
4826
// Response implementation
@@ -6307,13 +6336,11 @@ inline bool ClientImpl::send(Request &req, Response &res, Error &error) {
6307
6336
}
6308
6337
}
6309
6338
6339
+ auto ret = false ;
6310
6340
auto close_connection = !keep_alive_;
6311
- auto ret = process_socket (socket_, [&](Stream &strm) {
6312
- return handle_request (strm, req, res, close_connection, error);
6313
- });
6314
6341
6315
- // Briefly lock mutex in order to mark that a request is no longer ongoing
6316
- {
6342
+ auto se = detail::scope_exit<std::function< void ( void )>>([&]() {
6343
+ // Briefly lock mutex in order to mark that a request is no longer ongoing
6317
6344
std::lock_guard<std::mutex> guard (socket_mutex_);
6318
6345
socket_requests_in_flight_ -= 1 ;
6319
6346
if (socket_requests_in_flight_ <= 0 ) {
@@ -6327,7 +6354,11 @@ inline bool ClientImpl::send(Request &req, Response &res, Error &error) {
6327
6354
shutdown_socket (socket_);
6328
6355
close_socket (socket_);
6329
6356
}
6330
- }
6357
+ });
6358
+
6359
+ ret = process_socket (socket_, [&](Stream &strm) {
6360
+ return handle_request (strm, req, res, close_connection, error);
6361
+ });
6331
6362
6332
6363
if (!ret) {
6333
6364
if (error == Error::Success) { error = Error::Unknown; }
0 commit comments