Skip to content

Commit 3312b15

Browse files
committed
Tidy SIO1-Server(and client)
1 parent df8d669 commit 3312b15

3 files changed

Lines changed: 258 additions & 438 deletions

File tree

src/core/sio1-server.cc

Lines changed: 79 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,93 @@
2222
#include "core/psxemulator.h"
2323
#include "core/sio1.h"
2424

25+
PCSX::SIO1Client::SIO1Client(uv_tcp_t* server) : m_listener(g_system->m_eventBus) {
26+
m_loop = server->loop;
27+
uv_tcp_init(m_loop, &m_tcp);
28+
m_tcp.data = this;
29+
memset(m_buffer, 0, BUFFER_SIZE);
30+
}
31+
32+
bool PCSX::SIO1Client::accept(uv_tcp_t* server) {
33+
assert(m_status == SIO1ClientStatus::CLOSED);
34+
if (uv_accept(reinterpret_cast<uv_stream_t*>(server), reinterpret_cast<uv_stream_t*>(&m_tcp)) == 0) {
35+
uv_read_start(reinterpret_cast<uv_stream_t*>(&m_tcp), allocTrampoline, readTrampoline);
36+
m_status = SIO1ClientStatus::OPEN;
37+
}
38+
return m_status == SIO1ClientStatus::OPEN;
39+
}
40+
41+
void PCSX::SIO1Client::alloc(size_t suggestedSize, uv_buf_t* buf) {
42+
assert(!m_allocated);
43+
m_allocated = true;
44+
buf->base = m_buffer;
45+
buf->len = sizeof(m_buffer);
46+
}
47+
48+
void PCSX::SIO1Client::close() {
49+
if (m_status != SIO1ClientStatus::OPEN) return;
50+
m_status = SIO1ClientStatus::CLOSING;
51+
uv_close(reinterpret_cast<uv_handle_t*>(&m_tcp), closeCB);
52+
}
53+
54+
void PCSX::SIO1Client::processData(const Slice& slice) {
55+
PCSX::g_emulator->m_sio1->pushSlice(slice);
56+
PCSX::g_emulator->m_sio1->receiveCallback();
57+
}
58+
59+
void PCSX::SIO1Client::read(ssize_t nread, const uv_buf_t* buf) {
60+
m_allocated = false;
61+
if (nread <= 0) {
62+
close();
63+
return;
64+
}
65+
66+
Slice slice;
67+
slice.borrow(m_buffer, static_cast <uint32_t>(nread));
68+
processData(slice);
69+
}
70+
71+
void PCSX::SIO1Client::write(unsigned char c) {
72+
auto* req = new WriteRequest();
73+
req->m_slice.copy(static_cast<void*>(&c), 1);
74+
req->enqueue(this);
75+
}
76+
2577
PCSX::SIO1Server::SIO1Server() : m_listener(g_system->m_eventBus) {
2678
m_listener.listen<Events::SettingsLoaded>([this](const auto& event) {
2779
if (g_emulator->settings.get<Emulator::SettingDebugSettings>().get<Emulator::DebugSettings::SIO1Server>() &&
28-
(m_serverStatus != SERVER_STARTED)) {
80+
(m_serverStatus != SIO1ServerStatus::SERVER_STARTED)) {
2981
startServer(&g_emulator->m_loop, g_emulator->settings.get<Emulator::SettingDebugSettings>()
3082
.get<Emulator::DebugSettings::SIO1ServerPort>());
3183
}
3284
});
3385
m_listener.listen<Events::Quitting>([this](const auto& event) {
34-
if (m_serverStatus == SERVER_STARTED) stopServer();
86+
if (m_serverStatus == SIO1ServerStatus::SERVER_STARTED) stopServer();
3587
});
3688
}
3789

38-
void PCSX::SIO1Server::stopServer() {
39-
assert(m_serverStatus == SERVER_STARTED);
40-
m_serverStatus = SERVER_STOPPING;
41-
for (auto& client : m_clients) client.close();
42-
uv_close(reinterpret_cast<uv_handle_t*>(&m_server), closeCB);
90+
void PCSX::SIO1Server::closeCB(uv_handle_t* handle) {
91+
SIO1Server* self = static_cast<SIO1Server*>(handle->data);
92+
self->m_serverStatus = SIO1ServerStatus::SERVER_STOPPED;
93+
}
94+
95+
void PCSX::SIO1Server::onNewConnection(int status) {
96+
if (status < 0) return;
97+
SIO1Client* client = new SIO1Client(&m_server);
98+
if (client->accept(&m_server)) {
99+
m_clients.push_back(client);
100+
} else {
101+
delete client;
102+
}
103+
}
104+
105+
void PCSX::SIO1Server::onNewConnectionTrampoline(uv_stream_t* handle, int status) {
106+
SIO1Server* self = static_cast<SIO1Server*>(handle->data);
107+
self->onNewConnection(status);
43108
}
44109

45110
void PCSX::SIO1Server::startServer(uv_loop_t* loop, int port) {
46-
assert(m_serverStatus == SERVER_STOPPED);
111+
assert(m_serverStatus == SIO1ServerStatus::SERVER_STOPPED);
47112

48113
uv_tcp_init(loop, &m_server);
49114
m_server.data = this;
@@ -64,36 +129,12 @@ void PCSX::SIO1Server::startServer(uv_loop_t* loop, int port) {
64129
uv_close(reinterpret_cast<uv_handle_t*>(&m_server), closeCB);
65130
return;
66131
}
67-
m_serverStatus = SERVER_STARTED;
68-
}
69-
70-
void PCSX::SIO1Server::closeCB(uv_handle_t* handle) {
71-
SIO1Server* self = static_cast<SIO1Server*>(handle->data);
72-
self->m_serverStatus = SERVER_STOPPED;
73-
}
74-
75-
void PCSX::SIO1Server::onNewConnectionTrampoline(uv_stream_t* handle, int status) {
76-
SIO1Server* self = static_cast<SIO1Server*>(handle->data);
77-
self->onNewConnection(status);
78-
}
79-
80-
void PCSX::SIO1Server::onNewConnection(int status) {
81-
if (status < 0) return;
82-
SIO1Client* client = new SIO1Client(&m_server);
83-
if (client->accept(&m_server)) {
84-
m_clients.push_back(client);
85-
} else {
86-
delete client;
87-
}
132+
m_serverStatus = SIO1ServerStatus::SERVER_STARTED;
88133
}
89134

90-
PCSX::SIO1Client::SIO1Client(uv_tcp_t* server) : m_listener(g_system->m_eventBus) {
91-
m_loop = server->loop;
92-
uv_tcp_init(m_loop, &m_tcp);
93-
m_tcp.data = this;
94-
}
95-
96-
void PCSX::SIO1Client::processData(const Slice& slice) {
97-
PCSX::g_emulator->m_sio1->pushSlice(slice);
98-
PCSX::g_emulator->m_sio1->receiveCallback();
135+
void PCSX::SIO1Server::stopServer() {
136+
assert(m_serverStatus == SIO1ServerStatus::SERVER_STARTED);
137+
m_serverStatus = SIO1ServerStatus::SERVER_STOPPING;
138+
for (auto& client : m_clients) client.close();
139+
uv_close(reinterpret_cast<uv_handle_t*>(&m_server), closeCB);
99140
}

src/core/sio1-server.h

Lines changed: 88 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -19,147 +19,117 @@
1919

2020
#pragma once
2121

22-
#include <string>
2322
#include <queue>
23+
#include <string>
2424

2525
#include "core/debug.h"
2626
#include "core/psxemulator.h"
2727
#include "core/psxmem.h"
2828
#include "support/eventbus.h"
2929
#include "support/hashtable.h"
30-
#include "support/slice.h"
3130
#include "support/list.h"
32-
31+
#include "support/slice.h"
3332

3433
namespace PCSX {
35-
class SIO1Client;
36-
class SIO1Server;
37-
38-
class SIO1Client : public Intrusive::List<SIO1Client>::Node {
39-
public:
40-
SIO1Client(uv_tcp_t* server);
41-
typedef Intrusive::List<SIO1Client> ListType;
42-
43-
bool accept(uv_tcp_t* server) {
44-
assert(m_status == CLOSED);
45-
if (uv_accept(reinterpret_cast<uv_stream_t*>(server), reinterpret_cast<uv_stream_t*>(&m_tcp)) == 0) {
46-
uv_read_start(reinterpret_cast<uv_stream_t*>(&m_tcp), allocTrampoline, readTrampoline);
47-
m_status = OPEN;
48-
}
49-
return m_status == OPEN;
50-
}
51-
void close() {
52-
if (m_status != OPEN) return;
53-
m_status = CLOSING;
54-
uv_close(reinterpret_cast<uv_handle_t*>(&m_tcp), closeCB);
55-
}
34+
class SIO1Client;
35+
class SIO1Server;
5636

57-
private:
37+
class SIO1Client : public Intrusive::List<SIO1Client>::Node {
38+
public:
39+
SIO1Client(uv_tcp_t* server);
40+
typedef Intrusive::List<SIO1Client> ListType;
5841

59-
uv_tcp_t m_tcp;
60-
enum { CLOSED, OPEN, CLOSING } m_status = CLOSED;
61-
bool m_allocated = false;
42+
bool accept(uv_tcp_t* server);
43+
void close();
6244

63-
EventBus::Listener m_listener;
64-
uv_loop_t* m_loop;
65-
friend SIO1Server;
66-
static constexpr size_t BUFFER_SIZE = 4096;
45+
private:
46+
uv_tcp_t m_tcp;
47+
enum class SIO1ClientStatus { CLOSED, OPEN, CLOSING };
48+
SIO1ClientStatus m_status = SIO1ClientStatus::CLOSED;
6749

68-
static void allocTrampoline(uv_handle_t* handle, size_t suggestedSize, uv_buf_t* buf) {
69-
SIO1Client* client = static_cast<SIO1Client*>(handle->data);
70-
client->alloc(suggestedSize, buf);
71-
}
50+
bool m_allocated = false;
7251

73-
void alloc(size_t suggestedSize, uv_buf_t* buf) {
74-
assert(!m_allocated);
75-
m_allocated = true;
76-
buf->base = m_buffer;
77-
buf->len = sizeof(m_buffer);
78-
}
52+
EventBus::Listener m_listener;
53+
uv_loop_t* m_loop = 0;
54+
friend SIO1Server;
55+
static constexpr size_t BUFFER_SIZE = 4096;
7956

80-
static void readTrampoline(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
81-
SIO1Client* client = static_cast<SIO1Client*>(stream->data);
82-
client->read(nread, buf);
83-
}
84-
void read(ssize_t nread, const uv_buf_t* buf) {
85-
m_allocated = false;
86-
if (nread <= 0) {
87-
close();
88-
return;
89-
}
90-
91-
Slice slice;
92-
slice.borrow(m_buffer, nread);
93-
processData(slice);
94-
}
57+
void alloc(size_t suggestedSize, uv_buf_t* buf);
9558

96-
void write(unsigned char c)
97-
{
98-
auto* req = new WriteRequest();
99-
req->m_slice.copy(static_cast<void*>(&c), 1);
100-
req->enqueue(this);
101-
}
102-
static void closeCB(uv_handle_t* handle) {
103-
SIO1Client* client = static_cast<SIO1Client*>(handle->data);
104-
delete client;
105-
}
59+
static void allocTrampoline(uv_handle_t* handle, size_t suggestedSize, uv_buf_t* buf) {
60+
SIO1Client* client = static_cast<SIO1Client*>(handle->data);
61+
client->alloc(suggestedSize, buf);
62+
}
10663

107-
void processData(const Slice& slice);
108-
109-
struct WriteRequest : public Intrusive::HashTable<uintptr_t, WriteRequest>::Node {
110-
WriteRequest() {}
111-
WriteRequest(Slice&& slice) : m_slice(std::move(slice)) {}
112-
void enqueue(SIO1Client* client) {
113-
m_buf.base = static_cast<char*>(const_cast<void*>(m_slice.data()));
114-
m_buf.len = m_slice.size();
115-
client->m_requests.insert(reinterpret_cast<uintptr_t>(&m_req), this);
116-
uv_write(&m_req, reinterpret_cast<uv_stream_t*>(&client->m_tcp), &m_buf, 1, writeCB);
117-
}
118-
static void writeCB(uv_write_t* request, int status) {
119-
SIO1Client* client = static_cast<SIO1Client*>(request->handle->data);
120-
auto self = client->m_requests.find(reinterpret_cast<uintptr_t>(request));
121-
delete &*self;
122-
if (status != 0) client->close();
123-
}
124-
uv_buf_t m_buf;
125-
uv_write_t m_req;
126-
Slice m_slice;
127-
};
128-
Intrusive::HashTable<uintptr_t, WriteRequest> m_requests;
129-
130-
char m_buffer[BUFFER_SIZE];
131-
};
64+
static void closeCB(uv_handle_t* handle) {
65+
SIO1Client* client = static_cast<SIO1Client*>(handle->data);
66+
delete client;
67+
}
13268

133-
class SIO1Server {
134-
public:
135-
SIO1Server();
136-
//~SIO1Server() { }
137-
enum SIO1ServerStatus {
138-
SERVER_STOPPED,
139-
SERVER_STOPPING,
140-
SERVER_STARTED,
141-
};
142-
SIO1ServerStatus getServerStatus() { return m_serverStatus; }
69+
void processData(const Slice& slice);
14370

144-
void startServer(uv_loop_t* loop, int port = 6699);
145-
void stopServer();
71+
void read(ssize_t nread, const uv_buf_t* buf);
14672

73+
static void readTrampoline(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
74+
SIO1Client* client = static_cast<SIO1Client*>(stream->data);
75+
client->read(nread, buf);
76+
}
14777

148-
void write(unsigned char c) {
149-
for (auto& client : m_clients) client.write(c);
150-
}
78+
void write(unsigned char c);
15179

152-
private:
153-
static void onNewConnectionTrampoline(uv_stream_t* server, int status);
154-
void onNewConnection(int status);
155-
static void closeCB(uv_handle_t* handle);
156-
SIO1ServerStatus m_serverStatus = SERVER_STOPPED;
157-
uv_tcp_t m_server;
158-
uv_loop_t* m_loop;
159-
SIO1Client::ListType m_clients;
160-
EventBus::Listener m_listener;
161-
162-
std::string m_gotError;
80+
struct WriteRequest : public Intrusive::HashTable<uintptr_t, WriteRequest>::Node {
81+
WriteRequest() {}
82+
WriteRequest(Slice&& slice) : m_slice(std::move(slice)) {}
83+
void enqueue(SIO1Client* client) {
84+
m_buf.base = static_cast<char*>(const_cast<void*>(m_slice.data()));
85+
m_buf.len = m_slice.size();
86+
client->m_requests.insert(reinterpret_cast<uintptr_t>(&m_req), this);
87+
uv_write(&m_req, reinterpret_cast<uv_stream_t*>(&client->m_tcp), &m_buf, 1, writeCB);
88+
}
89+
static void writeCB(uv_write_t* request, int status) {
90+
SIO1Client* client = static_cast<SIO1Client*>(request->handle->data);
91+
auto self = client->m_requests.find(reinterpret_cast<uintptr_t>(request));
92+
delete &*self;
93+
if (status != 0) client->close();
94+
}
95+
uv_buf_t m_buf;
96+
uv_write_t m_req;
97+
Slice m_slice;
98+
};
99+
Intrusive::HashTable<uintptr_t, WriteRequest> m_requests;
100+
101+
char m_buffer[BUFFER_SIZE];
102+
};
103+
104+
class SIO1Server {
105+
public:
106+
SIO1Server();
107+
//~SIO1Server() { }
108+
enum class SIO1ServerStatus {
109+
SERVER_STOPPED,
110+
SERVER_STOPPING,
111+
SERVER_STARTED,
163112
};
113+
SIO1ServerStatus getServerStatus() { return m_serverStatus; }
114+
115+
void startServer(uv_loop_t* loop, int port = 6699);
116+
void stopServer();
117+
118+
void write(unsigned char c) {
119+
for (auto& client : m_clients) client.write(c);
120+
}
121+
122+
private:
123+
static void onNewConnectionTrampoline(uv_stream_t* server, int status);
124+
void onNewConnection(int status);
125+
static void closeCB(uv_handle_t* handle);
126+
SIO1ServerStatus m_serverStatus = SIO1ServerStatus::SERVER_STOPPED;
127+
uv_tcp_t m_server;
128+
uv_loop_t* m_loop;
129+
SIO1Client::ListType m_clients;
130+
EventBus::Listener m_listener;
131+
132+
std::string m_gotError;
133+
};
164134

165135
} // namespace PCSX

0 commit comments

Comments
 (0)