Skip to content

Commit 089b9da

Browse files
authored
Fix virtual call in ClientImpl::~ClientImpl() (#942)
* Fix virtual call in ClientImpl::~ClientImpl() This fixes a warning in clang tidy: > Call to virtual method 'ClientImpl::shutdown_ssl' during > destruction bypasses virtual dispatch ClientImpl::~ClientImpl() calls lock_socket_and_shutdown_and_close() that itself calls shutdown_ssl(). However, shutdown_ssl() is virtual and C++ does not perform virtual dispatch in destructors, which results in the wrong overload being called. This change adds a non-virtual shutdown_ssl_impl() function that is called from ~SSLClient(). We also inline sock_socket_and_shutdown_and_close() and removes the virtual call in ~ClientImpl(). * Inline and remove lock_socket_and_shutdown_and_close() The function only has one caller.
1 parent ba34ea4 commit 089b9da

File tree

1 file changed

+15
-14
lines changed

1 file changed

+15
-14
lines changed

httplib.h

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,10 +1050,6 @@ class ClientImpl {
10501050
void shutdown_socket(Socket &socket);
10511051
void close_socket(Socket &socket);
10521052

1053-
// Similar to shutdown_ssl and close_socket, this should NOT be called
1054-
// concurrently with a DIFFERENT thread sending requests from the socket
1055-
void lock_socket_and_shutdown_and_close();
1056-
10571053
bool process_request(Stream &strm, Request &req, Response &res,
10581054
bool close_connection, Error &error);
10591055

@@ -1412,6 +1408,7 @@ class SSLClient : public ClientImpl {
14121408
private:
14131409
bool create_and_connect_socket(Socket &socket, Error &error) override;
14141410
void shutdown_ssl(Socket &socket, bool shutdown_gracefully) override;
1411+
void shutdown_ssl_impl(Socket &socket, bool shutdown_socket);
14151412

14161413
bool process_socket(const Socket &socket,
14171414
std::function<bool(Stream &strm)> callback) override;
@@ -5258,7 +5255,11 @@ inline ClientImpl::ClientImpl(const std::string &host, int port,
52585255
host_and_port_(host_ + ":" + std::to_string(port_)),
52595256
client_cert_path_(client_cert_path), client_key_path_(client_key_path) {}
52605257

5261-
inline ClientImpl::~ClientImpl() { lock_socket_and_shutdown_and_close(); }
5258+
inline ClientImpl::~ClientImpl() {
5259+
std::lock_guard<std::mutex> guard(socket_mutex_);
5260+
shutdown_socket(socket_);
5261+
close_socket(socket_);
5262+
}
52625263

52635264
inline bool ClientImpl::is_valid() const { return true; }
52645265

@@ -5356,13 +5357,6 @@ inline void ClientImpl::close_socket(Socket &socket) {
53565357
socket.sock = INVALID_SOCKET;
53575358
}
53585359

5359-
inline void ClientImpl::lock_socket_and_shutdown_and_close() {
5360-
std::lock_guard<std::mutex> guard(socket_mutex_);
5361-
shutdown_ssl(socket_, true);
5362-
shutdown_socket(socket_);
5363-
close_socket(socket_);
5364-
}
5365-
53665360
inline bool ClientImpl::read_response_line(Stream &strm, const Request &req,
53675361
Response &res) {
53685362
std::array<char, 2048> buf;
@@ -5911,7 +5905,10 @@ inline bool ClientImpl::process_request(Stream &strm, Request &req,
59115905
// mutex during the process. It would be a bug to call it from a different
59125906
// thread since it's a thread-safety issue to do these things to the socket
59135907
// if another thread is using the socket.
5914-
lock_socket_and_shutdown_and_close();
5908+
std::lock_guard<std::mutex> guard(socket_mutex_);
5909+
shutdown_ssl(socket_, true);
5910+
shutdown_socket(socket_);
5911+
close_socket(socket_);
59155912
}
59165913

59175914
// Log
@@ -6864,7 +6861,7 @@ inline SSLClient::~SSLClient() {
68646861
// Make sure to shut down SSL since shutdown_ssl will resolve to the
68656862
// base function rather than the derived function once we get to the
68666863
// base class destructor, and won't free the SSL (causing a leak).
6867-
SSLClient::shutdown_ssl(socket_, true);
6864+
shutdown_ssl_impl(socket_, true);
68686865
}
68696866

68706867
inline bool SSLClient::is_valid() const { return ctx_; }
@@ -7043,6 +7040,10 @@ inline bool SSLClient::initialize_ssl(Socket &socket, Error &error) {
70437040
}
70447041

70457042
inline void SSLClient::shutdown_ssl(Socket &socket, bool shutdown_gracefully) {
7043+
shutdown_ssl_impl(socket, shutdown_gracefully);
7044+
}
7045+
7046+
inline void SSLClient::shutdown_ssl_impl(Socket &socket, bool shutdown_gracefully) {
70467047
if (socket.sock == INVALID_SOCKET) {
70477048
assert(socket.ssl == nullptr);
70487049
return;

0 commit comments

Comments
 (0)