From 907cda4c172936c6d5b7ea2ac1a3a0986c875853 Mon Sep 17 00:00:00 2001 From: ubq323 Date: Sat, 27 Apr 2024 21:27:12 +0100 Subject: use poll to check writing as well as reading; packet_reader handles both now --- server/main.ha | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) (limited to 'server/main.ha') 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], })?; -- cgit v1.2.3