Fix: Racy use of flags in TCPConnecter::CheckCallbacks

conected and aborted flags are used concurrently from multiple threads.
pull/163/head
Jonathan G Rennison 4 years ago committed by Niels Martin Hansen
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…
Cancel
Save