@@ -1038,7 +1038,6 @@ class ClientImpl {
1038
1038
ContentProviderWithoutLength content_provider_without_length,
1039
1039
const char *content_type);
1040
1040
1041
- // socket is const because this function is called when socket_mutex_ is not locked
1042
1041
virtual bool process_socket (const Socket &socket,
1043
1042
std::function<bool (Stream &strm)> callback);
1044
1043
virtual bool is_ssl () const ;
@@ -2065,7 +2064,8 @@ inline socket_t create_client_socket(const char *host, int port,
2065
2064
bool tcp_nodelay,
2066
2065
SocketOptions socket_options,
2067
2066
time_t timeout_sec, time_t timeout_usec,
2068
- const std::string &intf, std::atomic<Error> &error) {
2067
+ const std::string &intf,
2068
+ std::atomic<Error> &error) {
2069
2069
auto sock = create_socket (
2070
2070
host, port, 0 , tcp_nodelay, std::move (socket_options),
2071
2071
[&](socket_t sock, struct addrinfo &ai) -> bool {
@@ -2812,7 +2812,7 @@ inline bool write_data(Stream &strm, const char *d, size_t l) {
2812
2812
template <typename T>
2813
2813
inline bool write_content (Stream &strm, const ContentProvider &content_provider,
2814
2814
size_t offset, size_t length, T is_shutting_down,
2815
- Error &error) {
2815
+ std::atomic< Error> &error) {
2816
2816
size_t end_offset = offset + length;
2817
2817
auto ok = true ;
2818
2818
DataSink data_sink;
@@ -2848,7 +2848,7 @@ template <typename T>
2848
2848
inline bool write_content (Stream &strm, const ContentProvider &content_provider,
2849
2849
size_t offset, size_t length,
2850
2850
const T &is_shutting_down) {
2851
- Error error;
2851
+ std::atomic< Error> error;
2852
2852
return write_content (strm, content_provider, offset, length, is_shutting_down,
2853
2853
error);
2854
2854
}
@@ -2882,9 +2882,10 @@ write_content_without_length(Stream &strm,
2882
2882
}
2883
2883
2884
2884
template <typename T, typename U>
2885
- inline bool
2886
- write_content_chunked (Stream &strm, const ContentProvider &content_provider,
2887
- const T &is_shutting_down, U &compressor, Error &error) {
2885
+ inline bool write_content_chunked (Stream &strm,
2886
+ const ContentProvider &content_provider,
2887
+ const T &is_shutting_down, U &compressor,
2888
+ std::atomic<Error> &error) {
2888
2889
size_t offset = 0 ;
2889
2890
auto data_available = true ;
2890
2891
auto ok = true ;
@@ -2967,15 +2968,14 @@ template <typename T, typename U>
2967
2968
inline bool write_content_chunked (Stream &strm,
2968
2969
const ContentProvider &content_provider,
2969
2970
const T &is_shutting_down, U &compressor) {
2970
- Error error;
2971
+ std::atomic< Error> error;
2971
2972
return write_content_chunked (strm, content_provider, is_shutting_down,
2972
2973
compressor, error);
2973
2974
}
2974
2975
2975
2976
template <typename T>
2976
2977
inline bool redirect (T &cli, const Request &req, Response &res,
2977
- const std::string &path,
2978
- const std::string &location) {
2978
+ const std::string &path, const std::string &location) {
2979
2979
Request new_req = req;
2980
2980
new_req.path = path;
2981
2981
new_req.redirect_count_ -= 1 ;
@@ -4877,21 +4877,19 @@ inline bool ClientImpl::create_and_connect_socket(Socket &socket) {
4877
4877
return true ;
4878
4878
}
4879
4879
4880
- inline void ClientImpl::shutdown_ssl (Socket &socket, bool shutdown_gracefully) {
4881
- (void )socket;
4882
- (void )shutdown_gracefully;
4883
- // If there are any requests in flight from threads other than us, then it's
4884
- // a thread-unsafe race because individual ssl* objects are not thread-safe.
4880
+ inline void ClientImpl::shutdown_ssl (Socket & /* socket*/ ,
4881
+ bool /* shutdown_gracefully*/ ) {
4882
+ // If there are any requests in flight from threads other than us, then it's
4883
+ // a thread-unsafe race because individual ssl* objects are not thread-safe.
4885
4884
assert (socket_requests_in_flight_ == 0 ||
4886
4885
socket_requests_are_from_thread_ == std::this_thread::get_id ());
4887
4886
}
4888
4887
4889
4888
inline void ClientImpl::shutdown_socket (Socket &socket) {
4890
- if (socket.sock == INVALID_SOCKET)
4891
- return ;
4889
+ if (socket.sock == INVALID_SOCKET) { return ; }
4892
4890
detail::shutdown_socket (socket.sock );
4893
4891
}
4894
-
4892
+
4895
4893
inline void ClientImpl::close_socket (Socket &socket) {
4896
4894
// If there are requests in flight in another thread, usually closing
4897
4895
// the socket will be fine and they will simply receive an error when
@@ -4905,8 +4903,7 @@ inline void ClientImpl::close_socket(Socket &socket) {
4905
4903
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
4906
4904
assert (socket.ssl == nullptr );
4907
4905
#endif
4908
- if (socket.sock == INVALID_SOCKET)
4909
- return ;
4906
+ if (socket.sock == INVALID_SOCKET) { return ; }
4910
4907
detail::close_socket (socket.sock );
4911
4908
socket.sock = INVALID_SOCKET;
4912
4909
}
@@ -4917,7 +4914,7 @@ inline void ClientImpl::lock_socket_and_shutdown_and_close() {
4917
4914
shutdown_socket (socket_);
4918
4915
close_socket (socket_);
4919
4916
}
4920
-
4917
+
4921
4918
inline bool ClientImpl::read_response_line (Stream &strm, Response &res) {
4922
4919
std::array<char , 2048 > buf;
4923
4920
@@ -4952,17 +4949,17 @@ inline bool ClientImpl::send(const Request &req, Response &res) {
4952
4949
4953
4950
{
4954
4951
std::lock_guard<std::mutex> guard (socket_mutex_);
4955
- // Set this to false immediately - if it ever gets set to true by the end of the
4956
- // request, we know another thread instructed us to close the socket.
4952
+ // Set this to false immediately - if it ever gets set to true by the end of
4953
+ // the request, we know another thread instructed us to close the socket.
4957
4954
socket_should_be_closed_when_request_is_done_ = false ;
4958
4955
4959
4956
auto is_alive = false ;
4960
4957
if (socket_.is_open ()) {
4961
4958
is_alive = detail::select_write (socket_.sock , 0 , 0 ) > 0 ;
4962
4959
if (!is_alive) {
4963
- // Attempt to avoid sigpipe by shutting down nongracefully if it seems like
4964
- // the other side has already closed the connection
4965
- // Also, there cannot be any requests in flight from other threads since we locked
4960
+ // Attempt to avoid sigpipe by shutting down nongracefully if it seems
4961
+ // like the other side has already closed the connection Also, there
4962
+ // cannot be any requests in flight from other threads since we locked
4966
4963
// request_mutex_, so safe to close everything immediately
4967
4964
const bool shutdown_gracefully = false ;
4968
4965
shutdown_ssl (socket_, shutdown_gracefully);
@@ -4990,8 +4987,9 @@ inline bool ClientImpl::send(const Request &req, Response &res) {
4990
4987
#endif
4991
4988
}
4992
4989
4993
- // Mark the current socket as being in use so that it cannot be closed by anyone
4994
- // else while this request is ongoing, even though we will be releasing the mutex.
4990
+ // Mark the current socket as being in use so that it cannot be closed by
4991
+ // anyone else while this request is ongoing, even though we will be
4992
+ // releasing the mutex.
4995
4993
if (socket_requests_in_flight_ > 1 ) {
4996
4994
assert (socket_requests_are_from_thread_ == std::this_thread::get_id ());
4997
4995
}
@@ -5004,7 +5002,7 @@ inline bool ClientImpl::send(const Request &req, Response &res) {
5004
5002
return handle_request (strm, req, res, close_connection);
5005
5003
});
5006
5004
5007
- // Briefly lock mutex in order to mark that a request is no longer ongoing
5005
+ // Briefly lock mutex in order to mark that a request is no longer ongoing
5008
5006
{
5009
5007
std::lock_guard<std::mutex> guard (socket_mutex_);
5010
5008
socket_requests_in_flight_ -= 1 ;
@@ -5013,9 +5011,8 @@ inline bool ClientImpl::send(const Request &req, Response &res) {
5013
5011
socket_requests_are_from_thread_ = std::thread::id ();
5014
5012
}
5015
5013
5016
- if (socket_should_be_closed_when_request_is_done_ ||
5017
- close_connection ||
5018
- !ret ) {
5014
+ if (socket_should_be_closed_when_request_is_done_ || close_connection ||
5015
+ !ret) {
5019
5016
shutdown_ssl (socket_, true );
5020
5017
shutdown_socket (socket_);
5021
5018
close_socket (socket_);
@@ -5410,11 +5407,12 @@ inline bool ClientImpl::process_request(Stream &strm, const Request &req,
5410
5407
// for this to be safe. Maybe a code refactor (such as moving this out to
5411
5408
// the send function and getting rid of the recursiveness of the mutex)
5412
5409
// could make this more obvious.
5413
-
5414
- // This is safe to call because process_request is only called by handle_request
5415
- // which is only called by send, which locks the request mutex during the process.
5416
- // It would be a bug to call it from a different thread since it's a thread-safety
5417
- // issue to do these things to the socket if another thread is using the socket.
5410
+
5411
+ // This is safe to call because process_request is only called by
5412
+ // handle_request which is only called by send, which locks the request
5413
+ // mutex during the process. It would be a bug to call it from a different
5414
+ // thread since it's a thread-safety issue to do these things to the socket
5415
+ // if another thread is using the socket.
5418
5416
lock_socket_and_shutdown_and_close ();
5419
5417
}
5420
5418
@@ -5802,23 +5800,25 @@ inline size_t ClientImpl::is_socket_open() const {
5802
5800
5803
5801
inline void ClientImpl::stop () {
5804
5802
std::lock_guard<std::mutex> guard (socket_mutex_);
5805
- // There is no guarantee that this doesn't get overwritten later, but set it so that
5806
- // there is a good chance that any threads stopping as a result pick up this error.
5803
+ // There is no guarantee that this doesn't get overwritten later, but set it
5804
+ // so that there is a good chance that any threads stopping as a result pick
5805
+ // up this error.
5807
5806
error_ = Error::Canceled;
5808
-
5809
- // If there is anything ongoing right now, the ONLY thread-safe thing we can do
5810
- // is to shutdown_socket, so that threads using this socket suddenly discover
5811
- // they can't read/write any more and error out.
5812
- // Everything else (closing the socket, shutting ssl down) is unsafe because these
5813
- // actions are not thread-safe.
5807
+
5808
+ // If there is anything ongoing right now, the ONLY thread-safe thing we can
5809
+ // do is to shutdown_socket, so that threads using this socket suddenly
5810
+ // discover they can't read/write any more and error out. Everything else
5811
+ // (closing the socket, shutting ssl down) is unsafe because these actions are
5812
+ // not thread-safe.
5814
5813
if (socket_requests_in_flight_ > 0 ) {
5815
5814
shutdown_socket (socket_);
5816
- // Aside from that, we set a flag for the socket to be closed when we're done.
5815
+ // Aside from that, we set a flag for the socket to be closed when we're
5816
+ // done.
5817
5817
socket_should_be_closed_when_request_is_done_ = true ;
5818
5818
return ;
5819
5819
}
5820
5820
5821
- // Otherwise, sitll holding the mutex, we can shut everything down ourselves
5821
+ // Otherwise, sitll holding the mutex, we can shut everything down ourselves
5822
5822
shutdown_ssl (socket_, true );
5823
5823
shutdown_socket (socket_);
5824
5824
close_socket (socket_);
@@ -5951,10 +5951,9 @@ inline void ssl_delete(std::mutex &ctx_mutex, SSL *ssl,
5951
5951
bool shutdown_gracefully) {
5952
5952
// sometimes we may want to skip this to try to avoid SIGPIPE if we know
5953
5953
// the remote has closed the network connection
5954
- // Note that it is not always possible to avoid SIGPIPE, this is merely a best-efforts.
5955
- if (shutdown_gracefully) {
5956
- SSL_shutdown (ssl);
5957
- }
5954
+ // Note that it is not always possible to avoid SIGPIPE, this is merely a
5955
+ // best-efforts.
5956
+ if (shutdown_gracefully) { SSL_shutdown (ssl); }
5958
5957
5959
5958
std::lock_guard<std::mutex> guard (ctx_mutex);
5960
5959
SSL_free (ssl);
@@ -6215,8 +6214,8 @@ inline bool SSLServer::process_and_close_socket(socket_t sock) {
6215
6214
[&](Request &req) { req.ssl = ssl; });
6216
6215
});
6217
6216
6218
- // Shutdown gracefully if the result seemed successful, non-gracefully if the
6219
- // connection appeared to be closed.
6217
+ // Shutdown gracefully if the result seemed successful, non-gracefully if
6218
+ // the connection appeared to be closed.
6220
6219
const bool shutdown_gracefully = ret;
6221
6220
detail::ssl_delete (ctx_mutex_, ssl, shutdown_gracefully);
6222
6221
return ret;
@@ -6325,7 +6324,8 @@ inline bool SSLClient::connect_with_proxy(Socket &socket, Response &res,
6325
6324
req2.path = host_and_port_;
6326
6325
return process_request (strm, req2, res2, false );
6327
6326
})) {
6328
- // Thread-safe to close everything because we are assuming there are no requests in flight
6327
+ // Thread-safe to close everything because we are assuming there are no
6328
+ // requests in flight
6329
6329
shutdown_ssl (socket, true );
6330
6330
shutdown_socket (socket);
6331
6331
close_socket (socket);
@@ -6351,7 +6351,8 @@ inline bool SSLClient::connect_with_proxy(Socket &socket, Response &res,
6351
6351
true ));
6352
6352
return process_request (strm, req3, res3, false );
6353
6353
})) {
6354
- // Thread-safe to close everything because we are assuming there are no requests in flight
6354
+ // Thread-safe to close everything because we are assuming there are
6355
+ // no requests in flight
6355
6356
shutdown_ssl (socket, true );
6356
6357
shutdown_socket (socket);
6357
6358
close_socket (socket);
0 commit comments