summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan G Rennison <j.g.rennison@gmail.com>2020-05-06 23:41:25 +0100
committerNiels Martin Hansen <nielsm@indvikleren.dk>2020-06-18 19:57:34 +0200
commitb0f192abc4e8bdd9f5f46f6932b8308e32b7b4b6 (patch)
treee674c48def6dcf142b798ad015d1ced4d3d460ee
parentc167648d75428e6ff93f903de65df0cab0370bb6 (diff)
downloadopenttd-b0f192abc4e8bdd9f5f46f6932b8308e32b7b4b6.tar.xz
Fix: Racy use of flags in TCPConnecter::CheckCallbacks
conected and aborted flags are used concurrently from multiple threads.
-rw-r--r--src/network/core/tcp.h6
-rw-r--r--src/network/core/tcp_connect.cpp8
2 files changed, 9 insertions, 5 deletions
diff --git a/src/network/core/tcp.h b/src/network/core/tcp.h
index 08a09ca1a..ffa231497 100644
--- a/src/network/core/tcp.h
+++ b/src/network/core/tcp.h
@@ -15,6 +15,8 @@
#include "address.h"
#include "packet.h"
+#include <atomic>
+
/** The states of sending the packets. */
enum SendPacketsState {
SPS_CLOSED, ///< The connection got closed.
@@ -61,8 +63,8 @@ public:
*/
class TCPConnecter {
private:
- bool connected; ///< Whether we succeeded in making the connection
- bool aborted; ///< Whether we bailed out (i.e. connection making failed)
+ std::atomic<bool> connected;///< Whether we succeeded in making the connection
+ std::atomic<bool> aborted; ///< Whether we bailed out (i.e. connection making failed)
bool killed; ///< Whether we got killed
SOCKET sock; ///< The socket we're connecting with
diff --git a/src/network/core/tcp_connect.cpp b/src/network/core/tcp_connect.cpp
index 9448acb83..b4485cfe9 100644
--- a/src/network/core/tcp_connect.cpp
+++ b/src/network/core/tcp_connect.cpp
@@ -66,19 +66,21 @@ void TCPConnecter::Connect()
{
for (auto iter = _tcp_connecters.begin(); iter < _tcp_connecters.end(); /* nothing */) {
TCPConnecter *cur = *iter;
- if ((cur->connected || cur->aborted) && cur->killed) {
+ const bool connected = cur->connected.load();
+ const bool aborted = cur->aborted.load();
+ if ((connected || aborted) && cur->killed) {
iter = _tcp_connecters.erase(iter);
if (cur->sock != INVALID_SOCKET) closesocket(cur->sock);
delete cur;
continue;
}
- if (cur->connected) {
+ if (connected) {
iter = _tcp_connecters.erase(iter);
cur->OnConnect(cur->sock);
delete cur;
continue;
}
- if (cur->aborted) {
+ if (aborted) {
iter = _tcp_connecters.erase(iter);
cur->OnFailure();
delete cur;