2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
9 * @file tcp_connect.cpp Basic functions to create connections without blocking.
12 #include "../../stdafx.h"
13 #include "../../thread.h"
17 #include "../../safeguards.h"
19 /** List of connections that are currently being created */
20 static std::vector
<TCPConnecter
*> _tcp_connecters
;
23 * Create a new connecter for the given address
24 * @param address the (un)resolved address to connect to
26 TCPConnecter::TCPConnecter(const NetworkAddress
&address
) :
33 _tcp_connecters
.push_back(this);
34 if (!StartNewThread(nullptr, "ottd:tcp", &TCPConnecter::ThreadEntry
, this)) {
39 /** The actual connection function */
40 void TCPConnecter::Connect()
42 this->sock
= this->address
.Connect();
43 if (this->sock
== INVALID_SOCKET
) {
46 this->connected
= true;
51 * Entry point for the new threads.
52 * @param param the TCPConnecter instance to call Connect on.
54 /* static */ void TCPConnecter::ThreadEntry(TCPConnecter
*param
)
60 * Check whether we need to call the callback, i.e. whether we
61 * have connected or aborted and call the appropriate callback
62 * for that. It's done this way to ease on the locking that
63 * would otherwise be needed everywhere.
65 /* static */ void TCPConnecter::CheckCallbacks()
67 for (auto iter
= _tcp_connecters
.begin(); iter
< _tcp_connecters
.end(); /* nothing */) {
68 TCPConnecter
*cur
= *iter
;
69 const bool connected
= cur
->connected
.load();
70 const bool aborted
= cur
->aborted
.load();
71 if ((connected
|| aborted
) && cur
->killed
) {
72 iter
= _tcp_connecters
.erase(iter
);
73 if (cur
->sock
!= INVALID_SOCKET
) closesocket(cur
->sock
);
78 iter
= _tcp_connecters
.erase(iter
);
79 cur
->OnConnect(cur
->sock
);
84 iter
= _tcp_connecters
.erase(iter
);
93 /** Kill all connection attempts. */
94 /* static */ void TCPConnecter::KillAll()
96 for (TCPConnecter
*conn
: _tcp_connecters
) conn
->killed
= true;