Fix: destroying a TCPConnecter that was still resolving made illegal writes

Basically, we should join the resolve thread before we destruct
the object.
This commit is contained in:
Patric Stout 2021-05-08 14:45:23 +02:00 committed by Patric Stout
parent 664a8c3e85
commit 1b75a29d12
2 changed files with 10 additions and 2 deletions

View File

@ -18,6 +18,7 @@
#include <atomic>
#include <chrono>
#include <map>
#include <thread>
/** The states of sending the packets. */
enum SendPacketsState {
@ -65,6 +66,9 @@ public:
*/
class TCPConnecter {
private:
std::thread resolve_thread; ///< Thread used during resolving.
std::atomic<bool> is_resolved = false; ///< Whether resolving is done.
addrinfo *ai = nullptr; ///< getaddrinfo() allocated linked-list of resolved addresses.
std::vector<addrinfo *> addresses; ///< Addresses we can connect to.
std::map<SOCKET, NetworkAddress> sock_to_address; ///< Mapping of a socket to the real address it is connecting to. USed for DEBUG statements.
@ -73,7 +77,6 @@ private:
std::vector<SOCKET> sockets; ///< Pending connect() attempts.
std::chrono::steady_clock::time_point last_attempt; ///< Time we last tried to connect.
std::atomic<bool> is_resolved = false; ///< Whether resolving is done.
std::string connection_string; ///< Current address we are connecting to (before resolving).
void Resolve();

View File

@ -32,13 +32,17 @@ TCPConnecter::TCPConnecter(const std::string &connection_string, uint16 default_
_tcp_connecters.push_back(this);
if (!StartNewThread(nullptr, "ottd:resolve", &TCPConnecter::ResolveThunk, this)) {
if (!StartNewThread(&this->resolve_thread, "ottd:resolve", &TCPConnecter::ResolveThunk, this)) {
this->Resolve();
}
}
TCPConnecter::~TCPConnecter()
{
if (this->resolve_thread.joinable()) {
this->resolve_thread.join();
}
for (const auto &socket : this->sockets) {
closesocket(socket);
}
@ -187,6 +191,7 @@ void TCPConnecter::Resolve()
this->ai = ai;
this->OnResolved(ai);
this->is_resolved = true;
}