summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2024-04-27 21:27:12 +0100
committerubq323 <ubq323@ubq323.website>2024-04-27 21:27:17 +0100
commit907cda4c172936c6d5b7ea2ac1a3a0986c875853 (patch)
tree46020134dd1b8c3434fde07ab6cf9346391bf70b /server
parent4c7156d0b20447e29f354679acdcd28480df91bc (diff)
use poll to check writing as well as reading; packet_reader handles both now
Diffstat (limited to 'server')
-rw-r--r--server/main.ha47
1 files changed, 30 insertions, 17 deletions
diff --git a/server/main.ha b/server/main.ha
index 475d19a..f78bf0c 100644
--- a/server/main.ha
+++ b/server/main.ha
@@ -32,7 +32,6 @@ type server_state = struct {
type connection = struct {
pr: packet_reader::packet_reader,
- sock: net::socket,
pos: pos,
should_delete: bool,
};
@@ -90,13 +89,17 @@ fn loop(state: *server_state, timeout: time::duration) void = {
let pollfds: []poll::pollfd = [];
append(pollfds, poll::pollfd {
fd = state.listener,
- events = poll::event::POLLIN,
+ events = poll::event::POLLIN | poll::event::POLLOUT,
...
});
for (const conn &.. state.connections) {
+ const events = if (len(conn.pr.wgood) > 0)
+ poll::event::POLLIN | poll::event::POLLOUT
+ else
+ poll::event::POLLIN;
append(pollfds, poll::pollfd {
- fd = conn.sock,
- events = poll::event::POLLIN,
+ fd = conn.pr.sock,
+ events = events,
...
});
};
@@ -107,8 +110,7 @@ fn loop(state: *server_state, timeout: time::duration) void = {
if (0 != pollfds[0].revents & poll::event::POLLIN) {
const new_conn = tcp::accept(pollfds[0].fd)!;
append(state.connections, connection {
- sock = new_conn,
- pr = packet_reader::new(),
+ pr = packet_reader::new(new_conn),
pos = (0,0),
should_delete = false,
});
@@ -130,8 +132,12 @@ fn loop(state: *server_state, timeout: time::duration) void = {
for (let pollfd_idx = 1z: size; pollfd_idx < len(pollfds); pollfd_idx += 1) {
const conn_idx = pollfd_idx - 1;
if (state.connections[conn_idx].should_delete) continue;
- if (0 != pollfds[conn_idx+1].revents & poll::event::POLLIN) {
- read_from_connection(state, conn_idx);
+
+ const revents = pollfds[conn_idx+1].revents;
+ const should_read = 0 != revents & poll::event::POLLIN;
+ const should_write = 0 != revents & poll::event::POLLOUT;
+ if (should_read || should_write) {
+ read_from_connection(state, conn_idx, should_read, should_write);
};
};
@@ -146,6 +152,8 @@ fn perform_deletions(state: *server_state) void = {
const conn = state.connections[i];
if (conn.should_delete) {
fmt::printfln("deleting conn {}",i)!;
+ packet_reader::finish(&conn.pr);
+ io::close(conn.pr.sock): void;
delete(state.connections[i]);
};
};
@@ -154,14 +162,19 @@ fn perform_deletions(state: *server_state) void = {
fn greet_connection(state: *server_state, conn_idx: size)
(void|io::error) = {
const conn = state.connections[conn_idx];
- io::write(conn.sock, [VERSION])?;
+ io::write(conn.pr.sock, [VERSION])?;
};
-fn read_from_connection(state: *server_state, conn_idx: size) void = {
+fn read_from_connection(
+ state: *server_state,
+ conn_idx: size,
+ should_read: bool,
+ should_write: bool,
+) void = {
const conn = &state.connections[conn_idx];
- match (packet_reader::read(&conn.pr, conn.sock)) {
+ match (packet_reader::service(&conn.pr, should_read, should_write)) {
case let err: io::error =>
fmt::printfln("#{} error: {}", conn_idx, io::strerror(err))!;
conn.should_delete = true;
@@ -169,7 +182,7 @@ fn read_from_connection(state: *server_state, conn_idx: size) void = {
fmt::printfln("#{} disconnect", conn_idx)!;
conn.should_delete = true;
case void =>
- for (true) match (packet_reader::next(&conn.pr)) {
+ for (true) match (packet_reader::read_next(&conn.pr)) {
// xxx foreach loop seems to break match exhaustivity here
// investigate that at some point
case done => break;
@@ -192,7 +205,7 @@ fn handle_packet(
state: *server_state,
conn_idx: size,
packet: packet_reader::packet
-) (void|io::error) = {
+) (void|io::error|packet_reader::error) = {
const conn = &state.connections[conn_idx];
match (packet) {
case let op: packet_reader::packet_drawop =>
@@ -207,11 +220,11 @@ fn handle_packet(
const other_conn = &state.connections[other_idx];
if (other_conn.should_delete) continue;
// fmt::printfln("\t -> #{}",other_idx)!;
- match (packet_reader::send(other_conn.sock, packet)) {
+ match (packet_reader::write(&other_conn.pr, packet)) {
case void => yield;
- case let e: io::error =>
+ case let e: packet_reader::error =>
fmt::printfln("couldn't send to #{}: {}",
- other_idx, io::strerror(e))!;
+ other_idx, e: str)!;
other_conn.should_delete = true;
};
};
@@ -225,7 +238,7 @@ fn handle_packet(
conn_idx, world_pos.0, world_pos.1)!;
const pic = ensure_chunk(state, world_pos);
- packet_reader::send(conn.sock, packet_reader::packet_sendchunk {
+ packet_reader::write(&conn.pr, packet_reader::packet_sendchunk {
world_pos = world_pos,
chunk_data = pic.d[..pic.w*pic.h],
})?;