Skip to content

Commit b67cccd

Browse files
fix host game client connecting too early
unfortunately, still crashes when ssock add_fd fails
1 parent 8aa92dc commit b67cccd

File tree

6 files changed

+46
-11
lines changed

6 files changed

+46
-11
lines changed

game/src/engine.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,9 @@ void Engine::start_server(uint16_t port) {
505505
}, port);
506506
t2.detach();
507507

508+
server->wait_active(true);
508509
start_client_now("127.0.0.1", port, info);
510+
509511
guard.good = true;
510512
} catch (std::exception &e) {
511513
fprintf(stderr, "%s: cannot start server: %s\n", func, e.what());

game/src/net/client.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ LocalClient::LocalClient()
1313
: IClient(), IServer(), w() {}
1414

1515
void LocalClient::close() {
16-
m_active = false;
16+
set_active(false);
1717
stop();
1818
}
1919

game/src/net/net.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,8 @@ int ServerSocket::mainloop(uint16_t port, int backlog, ServerSocketController &c
10401040
s.set_nonblocking();
10411041
step = false;
10421042

1043+
ctl.started();
1044+
10431045
for (int nfds; (nfds = epoll_wait(h, events.data(), events.size(), -1)) >= 0; step = false) {
10441046
for (int i = 0; i < nfds; ++i)
10451047
if (!event_step(i)) {

game/src/net/net.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class TcpSocket final {
7171
public:
7272
TcpSocket();
7373
TcpSocket(SOCKET s) : s((int)s) {}
74-
TcpSocket(const TcpSocket &) = delete;
74+
TcpSocket(const TcpSocket&) = delete;
7575
TcpSocket(TcpSocket &&s) noexcept : s(s.s.load()) { s.s.store((int)INVALID_SOCKET); }
7676
~TcpSocket();
7777

@@ -166,6 +166,9 @@ class ServerSocketController {
166166
/* A peer has just left or has been kicked from this server. */
167167
virtual void dropped(ServerSocket &s, const Peer &p) = 0;
168168

169+
/* Server has started and is actively listening to incoming connections. */
170+
virtual void started() = 0;
171+
169172
/* Server has been stopped. */
170173
virtual void stopped() = 0;
171174

game/src/server.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,27 @@
77

88
namespace aoe {
99

10+
IServer::IServer() : cv_active(), lk_active(), m_active(false) {}
11+
12+
bool IServer::active() noexcept {
13+
std::lock_guard<std::mutex> lk(lk_active);
14+
return m_active;
15+
}
16+
17+
void IServer::set_active(bool v) {
18+
{
19+
std::lock_guard<std::mutex> lk(lk_active);
20+
m_active = v;
21+
}
22+
cv_active.notify_all();
23+
}
24+
25+
void IServer::wait_active(bool exp) {
26+
std::unique_lock<std::mutex> lk(lk_active);
27+
while (m_active != exp)
28+
cv_active.wait(lk);
29+
}
30+
1031
Server::Server()
1132
: ServerSocketController(), IServer()
1233
, s(), m_running(false), m_peers(), port(0), protocol(0), peers(), refs(), w(), civs() {}
@@ -241,14 +262,16 @@ int Server::mainloop(uint16_t port, uint16_t protocol, bool testing) {
241262
old_lang.collect_civs(civnames);
242263
}
243264

244-
m_active = true;
245-
int r = s.mainloop(port, 10, *this);
265+
return s.mainloop(port, 10, *this);
266+
}
246267

247-
return r;
268+
void Server::started() {
269+
set_active(true);
248270
}
249271

250272
void Server::stop() {
251-
m_running = m_active = false;
273+
m_running = false;
274+
set_active(false);
252275
}
253276

254277
void Server::close() {

game/src/server.hpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <thread>
1414
#include <variant>
1515
#include <optional>
16+
#include <condition_variable>
1617

1718
#include "game.hpp"
1819
#include "debug.hpp"
@@ -179,14 +180,17 @@ class World final {
179180
};
180181

181182
class IServer {
182-
protected:
183-
std::atomic<bool> m_active;
183+
private:
184+
std::condition_variable cv_active;
185+
std::mutex lk_active;
186+
bool m_active;
184187
public:
185-
IServer() : m_active(false) {}
186-
188+
IServer();
187189
virtual ~IServer() = default;
188190

189-
bool active() const noexcept { return m_active; }
191+
bool active() noexcept;
192+
void set_active(bool v);
193+
void wait_active(bool exp);
190194

191195
virtual bool is_running() const noexcept =0;
192196
virtual void close() =0;
@@ -214,6 +218,7 @@ class Server final : public ServerSocketController, public IServer {
214218
~Server() override;
215219

216220
void stop();
221+
void started() override;
217222
void close() override; // this will block till everything is stopped
218223

219224
int mainloop(uint16_t port, uint16_t protocol, bool testing=false);

0 commit comments

Comments
 (0)