mirror of https://github.com/OpenTTD/OpenTTD
Fix: Racy use of flags in TCPConnecter::CheckCallbacks
conected and aborted flags are used concurrently from multiple threads.pull/8218/head
parent
c167648d75
commit
b0f192abc4
|
@ -15,6 +15,8 @@
|
||||||
#include "address.h"
|
#include "address.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
/** The states of sending the packets. */
|
/** The states of sending the packets. */
|
||||||
enum SendPacketsState {
|
enum SendPacketsState {
|
||||||
SPS_CLOSED, ///< The connection got closed.
|
SPS_CLOSED, ///< The connection got closed.
|
||||||
|
@ -61,8 +63,8 @@ public:
|
||||||
*/
|
*/
|
||||||
class TCPConnecter {
|
class TCPConnecter {
|
||||||
private:
|
private:
|
||||||
bool connected; ///< Whether we succeeded in making the connection
|
std::atomic<bool> connected;///< Whether we succeeded in making the connection
|
||||||
bool aborted; ///< Whether we bailed out (i.e. connection making failed)
|
std::atomic<bool> aborted; ///< Whether we bailed out (i.e. connection making failed)
|
||||||
bool killed; ///< Whether we got killed
|
bool killed; ///< Whether we got killed
|
||||||
SOCKET sock; ///< The socket we're connecting with
|
SOCKET sock; ///< The socket we're connecting with
|
||||||
|
|
||||||
|
|
|
@ -66,19 +66,21 @@ void TCPConnecter::Connect()
|
||||||
{
|
{
|
||||||
for (auto iter = _tcp_connecters.begin(); iter < _tcp_connecters.end(); /* nothing */) {
|
for (auto iter = _tcp_connecters.begin(); iter < _tcp_connecters.end(); /* nothing */) {
|
||||||
TCPConnecter *cur = *iter;
|
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);
|
iter = _tcp_connecters.erase(iter);
|
||||||
if (cur->sock != INVALID_SOCKET) closesocket(cur->sock);
|
if (cur->sock != INVALID_SOCKET) closesocket(cur->sock);
|
||||||
delete cur;
|
delete cur;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cur->connected) {
|
if (connected) {
|
||||||
iter = _tcp_connecters.erase(iter);
|
iter = _tcp_connecters.erase(iter);
|
||||||
cur->OnConnect(cur->sock);
|
cur->OnConnect(cur->sock);
|
||||||
delete cur;
|
delete cur;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cur->aborted) {
|
if (aborted) {
|
||||||
iter = _tcp_connecters.erase(iter);
|
iter = _tcp_connecters.erase(iter);
|
||||||
cur->OnFailure();
|
cur->OnFailure();
|
||||||
delete cur;
|
delete cur;
|
||||||
|
|
Loading…
Reference in New Issue