mirror of
https://github.com/open-goal/jak-project
synced 2026-08-18 21:57:54 -04:00
game: pull out single-client logic from XSocketServer
This commit is contained in:
@@ -25,16 +25,8 @@ XSocketServer::~XSocketServer() {
|
||||
}
|
||||
|
||||
void XSocketServer::shutdown_server() {
|
||||
// Cleanup the accept thread
|
||||
if (accept_thread_running) {
|
||||
kill_accept_thread = true;
|
||||
accept_thread.join();
|
||||
accept_thread_running = false;
|
||||
}
|
||||
|
||||
// Close the listening and accepted socket socket
|
||||
close_server_socket();
|
||||
close_socket(accepted_socket);
|
||||
}
|
||||
|
||||
bool XSocketServer::init_server() {
|
||||
@@ -83,8 +75,8 @@ bool XSocketServer::init_server() {
|
||||
}
|
||||
|
||||
server_initialized = true;
|
||||
accept_thread = std::thread(&XSocketServer::accept_thread_func, this);
|
||||
fmt::print("[XSocketServer:{}] awaiting connections\n", tcp_port);
|
||||
fmt::print("[XSocketServer:{}] initialized\n", tcp_port);
|
||||
post_init();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -92,29 +84,3 @@ void XSocketServer::close_server_socket() {
|
||||
close_socket(listening_socket);
|
||||
listening_socket = -1;
|
||||
}
|
||||
|
||||
void XSocketServer::accept_thread_func() {
|
||||
socklen_t l = sizeof(addr);
|
||||
while (!kill_accept_thread) {
|
||||
if (accepted_socket == -1) {
|
||||
this->accepted_socket = accept_socket(listening_socket, (sockaddr*)&addr, &l);
|
||||
fmt::print("Accept Socket in XSocketServer: {}\n", this->accepted_socket);
|
||||
set_socket_timeout(this->accepted_socket, 100000);
|
||||
write_on_accept();
|
||||
client_connected = true;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(50000));
|
||||
}
|
||||
}
|
||||
|
||||
bool XSocketServer::wait_for_connection() {
|
||||
return client_connected;
|
||||
}
|
||||
|
||||
void XSocketServer::lock() {
|
||||
server_mutex.lock();
|
||||
}
|
||||
|
||||
void XSocketServer::unlock() {
|
||||
server_mutex.unlock();
|
||||
}
|
||||
|
||||
@@ -11,28 +11,25 @@
|
||||
class XSocketServer {
|
||||
public:
|
||||
static constexpr int DEF_BUFFER_SIZE = 32 * 1024 * 1024;
|
||||
XSocketServer(const XSocketServer&) = delete;
|
||||
XSocketServer& operator=(const XSocketServer&) = delete;
|
||||
XSocketServer(std::function<bool()> shutdown_callback,
|
||||
int _tcp_port,
|
||||
int _buffer_size = DEF_BUFFER_SIZE);
|
||||
virtual ~XSocketServer();
|
||||
|
||||
XSocketServer(const XSocketServer&) = delete;
|
||||
XSocketServer& operator=(const XSocketServer&) = delete;
|
||||
|
||||
bool init_server();
|
||||
void shutdown_server();
|
||||
void close_server_socket();
|
||||
|
||||
bool wait_for_connection();
|
||||
void lock();
|
||||
void unlock();
|
||||
|
||||
// Abstract methods -- use-case dependent
|
||||
virtual void write_on_accept() = 0;
|
||||
virtual void post_init() = 0;
|
||||
|
||||
protected:
|
||||
int tcp_port;
|
||||
struct sockaddr_in addr = {};
|
||||
int listening_socket = -1;
|
||||
int accepted_socket = -1;
|
||||
std::vector<char> buffer;
|
||||
|
||||
bool kill_accept_thread = false;
|
||||
@@ -41,9 +38,4 @@ class XSocketServer {
|
||||
bool client_connected = false;
|
||||
|
||||
std::function<bool()> want_exit_callback;
|
||||
std::thread accept_thread;
|
||||
|
||||
std::mutex server_mutex;
|
||||
|
||||
void accept_thread_func();
|
||||
};
|
||||
|
||||
+1
-1
@@ -93,7 +93,7 @@ void deci2_runner(SystemThreadInterface& iface) {
|
||||
lg::debug("[DECI2] Waiting for listener...");
|
||||
bool saw_listener = false;
|
||||
while (!iface.get_want_exit()) {
|
||||
if (server.wait_for_connection()) {
|
||||
if (server.is_client_connected()) {
|
||||
if (!saw_listener) {
|
||||
lg::debug("[DECI2] Connected!");
|
||||
}
|
||||
|
||||
@@ -14,11 +14,46 @@
|
||||
|
||||
#include "third-party/fmt/core.h"
|
||||
|
||||
void Deci2Server::write_on_accept() {
|
||||
u32 versions[2] = {versions::GOAL_VERSION_MAJOR, versions::GOAL_VERSION_MINOR};
|
||||
lock();
|
||||
write_to_socket(accepted_socket, (char*)&versions, 8);
|
||||
unlock();
|
||||
#ifdef _WIN32
|
||||
#define NOMINMAX
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <WinSock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
#endif
|
||||
|
||||
Deci2Server::~Deci2Server() {
|
||||
// Cleanup the accept thread
|
||||
if (accept_thread_running) {
|
||||
kill_accept_thread = true;
|
||||
accept_thread.join();
|
||||
accept_thread_running = false;
|
||||
}
|
||||
close_socket(accepted_socket);
|
||||
}
|
||||
|
||||
void Deci2Server::post_init() {
|
||||
fmt::print("[Deci2Server:{}] awaiting connections\n", tcp_port);
|
||||
accept_thread = std::thread(&Deci2Server::accept_thread_func, this);
|
||||
}
|
||||
|
||||
void Deci2Server::accept_thread_func() {
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
while (!kill_accept_thread) {
|
||||
if (accepted_socket == -1) {
|
||||
accepted_socket = accept_socket(listening_socket, (sockaddr*)&addr, &addr_len);
|
||||
set_socket_timeout(accepted_socket, 100000);
|
||||
u32 versions[2] = {versions::GOAL_VERSION_MAJOR, versions::GOAL_VERSION_MINOR};
|
||||
write_to_socket(accepted_socket, (char*)&versions, 8);
|
||||
client_connected = true;
|
||||
return; // stop accepting connections
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(50000));
|
||||
}
|
||||
}
|
||||
|
||||
bool Deci2Server::is_client_connected() {
|
||||
return client_connected;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -48,6 +83,10 @@ void Deci2Server::send_proto_ready(Deci2Driver* drivers, int* driver_count) {
|
||||
}
|
||||
|
||||
void Deci2Server::read_data() {
|
||||
if (!is_client_connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int desired_size = (int)sizeof(Deci2Header);
|
||||
int got = 0;
|
||||
|
||||
@@ -133,3 +172,11 @@ void Deci2Server::send_data(void* buf, u16 len) {
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
void Deci2Server::lock() {
|
||||
server_mutex.lock();
|
||||
}
|
||||
|
||||
void Deci2Server::unlock() {
|
||||
server_mutex.unlock();
|
||||
}
|
||||
|
||||
@@ -10,17 +10,31 @@
|
||||
class Deci2Server : public XSocketServer {
|
||||
public:
|
||||
using XSocketServer::XSocketServer;
|
||||
virtual ~Deci2Server();
|
||||
|
||||
void post_init() override;
|
||||
void pre_shutdown() override;
|
||||
|
||||
void write_on_accept() override;
|
||||
void read_data();
|
||||
void send_data(void* buf, u16 len);
|
||||
|
||||
bool is_client_connected();
|
||||
void wait_for_protos_ready();
|
||||
void send_proto_ready(Deci2Driver* drivers, int* driver_count);
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
|
||||
private:
|
||||
bool protocols_ready = false;
|
||||
std::condition_variable cv;
|
||||
Deci2Driver* d2_drivers = nullptr;
|
||||
int* d2_driver_count = nullptr;
|
||||
|
||||
int accepted_socket = -1;
|
||||
|
||||
std::thread accept_thread;
|
||||
std::mutex server_mutex;
|
||||
|
||||
void accept_thread_func();
|
||||
};
|
||||
|
||||
@@ -40,26 +40,26 @@ TEST(Listener, ListenToNothing) {
|
||||
TEST(Listener, DeciCheckNoListener) {
|
||||
Deci2Server s(always_false, DECI2_PORT);
|
||||
EXPECT_TRUE(s.init_server());
|
||||
EXPECT_FALSE(s.wait_for_connection());
|
||||
EXPECT_FALSE(s.wait_for_connection());
|
||||
EXPECT_FALSE(s.wait_for_connection());
|
||||
EXPECT_FALSE(s.is_client_connected());
|
||||
EXPECT_FALSE(s.is_client_connected());
|
||||
EXPECT_FALSE(s.is_client_connected());
|
||||
}
|
||||
|
||||
TEST(Listener, CheckConnectionStaysAlive) {
|
||||
Deci2Server s(always_false, DECI2_PORT);
|
||||
EXPECT_TRUE(s.init_server());
|
||||
EXPECT_FALSE(s.wait_for_connection());
|
||||
EXPECT_FALSE(s.is_client_connected());
|
||||
Listener l;
|
||||
EXPECT_FALSE(s.wait_for_connection());
|
||||
EXPECT_FALSE(s.is_client_connected());
|
||||
bool connected = l.connect_to_target();
|
||||
EXPECT_TRUE(connected);
|
||||
// TODO - some sort of backoff and retry would be better
|
||||
while (connected && !s.wait_for_connection()) {
|
||||
while (connected && !s.is_client_connected()) {
|
||||
}
|
||||
|
||||
EXPECT_TRUE(s.wait_for_connection());
|
||||
EXPECT_TRUE(s.is_client_connected());
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
EXPECT_TRUE(s.wait_for_connection());
|
||||
EXPECT_TRUE(s.is_client_connected());
|
||||
EXPECT_TRUE(l.is_connected());
|
||||
}
|
||||
|
||||
@@ -67,19 +67,19 @@ TEST(Listener, DeciThenListener) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
Deci2Server s(always_false, DECI2_PORT);
|
||||
EXPECT_TRUE(s.init_server());
|
||||
EXPECT_FALSE(s.wait_for_connection());
|
||||
EXPECT_FALSE(s.wait_for_connection());
|
||||
EXPECT_FALSE(s.wait_for_connection());
|
||||
EXPECT_FALSE(s.is_client_connected());
|
||||
EXPECT_FALSE(s.is_client_connected());
|
||||
EXPECT_FALSE(s.is_client_connected());
|
||||
Listener l;
|
||||
EXPECT_FALSE(s.wait_for_connection());
|
||||
EXPECT_FALSE(s.wait_for_connection());
|
||||
EXPECT_FALSE(s.is_client_connected());
|
||||
EXPECT_FALSE(s.is_client_connected());
|
||||
bool connected = l.connect_to_target();
|
||||
EXPECT_TRUE(connected);
|
||||
// TODO - some sort of backoff and retry would be better
|
||||
while (connected && !s.wait_for_connection()) {
|
||||
while (connected && !s.is_client_connected()) {
|
||||
}
|
||||
|
||||
EXPECT_TRUE(s.wait_for_connection());
|
||||
EXPECT_TRUE(s.is_client_connected());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,12 +87,12 @@ TEST(Listener, DeciThenListener2) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
Deci2Server s(always_false, DECI2_PORT);
|
||||
EXPECT_TRUE(s.init_server());
|
||||
EXPECT_FALSE(s.wait_for_connection());
|
||||
EXPECT_FALSE(s.wait_for_connection());
|
||||
EXPECT_FALSE(s.wait_for_connection());
|
||||
EXPECT_FALSE(s.is_client_connected());
|
||||
EXPECT_FALSE(s.is_client_connected());
|
||||
EXPECT_FALSE(s.is_client_connected());
|
||||
Listener l;
|
||||
EXPECT_FALSE(s.wait_for_connection());
|
||||
EXPECT_FALSE(s.wait_for_connection());
|
||||
EXPECT_FALSE(s.is_client_connected());
|
||||
EXPECT_FALSE(s.is_client_connected());
|
||||
EXPECT_TRUE(l.connect_to_target());
|
||||
}
|
||||
}
|
||||
@@ -103,11 +103,11 @@ TEST(Listener, ListenerThenDeci) {
|
||||
EXPECT_FALSE(l.connect_to_target());
|
||||
Deci2Server s(always_false, DECI2_PORT);
|
||||
EXPECT_TRUE(s.init_server());
|
||||
EXPECT_FALSE(s.wait_for_connection());
|
||||
EXPECT_FALSE(s.is_client_connected());
|
||||
bool connected = l.connect_to_target();
|
||||
EXPECT_TRUE(connected);
|
||||
// TODO - some sort of backoff and retry would be better
|
||||
while (connected && !s.wait_for_connection()) {
|
||||
while (connected && !s.is_client_connected()) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user