mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
tcp: remove the accept timer and unnecessary pool allocations
This commit is contained in:
@ -11,9 +11,6 @@ const SocketPool = std.heap.MemoryPool(xev.TCP);
|
||||
const BufferPool = std.heap.MemoryPool([1024]u8);
|
||||
const log = std.log.scoped(.tcp_thread);
|
||||
|
||||
/// Acceptor polling rate in milliseconds
|
||||
const ACCEPTOR_RATE = 1;
|
||||
|
||||
/// A wrapper around the TCP server socket
|
||||
pub const Server = @This();
|
||||
|
||||
@ -35,9 +32,6 @@ loop: xev.Loop,
|
||||
/// Server socket
|
||||
socket: xev.TCP,
|
||||
|
||||
/// Timer for accepting connections
|
||||
acceptor: xev.Timer,
|
||||
|
||||
/// Number of clients connected
|
||||
clients_count: usize,
|
||||
|
||||
@ -60,7 +54,6 @@ pub fn init(
|
||||
.buf_pool = BufferPool.init(alloc),
|
||||
.loop = try xev.Loop.init(.{}),
|
||||
.socket = try xev.TCP.init(addr),
|
||||
.acceptor = try xev.Timer.init(),
|
||||
.clients_count = 0,
|
||||
.addr = addr,
|
||||
.max_clients = max_clients,
|
||||
@ -104,7 +97,6 @@ pub fn deinit(self: *Server) void {
|
||||
self.sock_pool.deinit();
|
||||
self.buf_pool.deinit();
|
||||
self.loop.deinit();
|
||||
self.acceptor.deinit();
|
||||
}
|
||||
|
||||
/// Starts the timer which tries to accept connections
|
||||
@ -120,7 +112,7 @@ pub fn start(self: *Server) !void {
|
||||
return error.OutOfMemory;
|
||||
};
|
||||
|
||||
self.acceptor.run(&self.loop, c, ACCEPTOR_RATE, Server, self, acceptor);
|
||||
self.socket.accept(&self.loop, c, Server, self, acceptHandler);
|
||||
while (true) {
|
||||
try self.loop.run(.until_done);
|
||||
}
|
||||
@ -133,38 +125,9 @@ pub fn destroyBuffer(self: *Server, buf: []const u8) void {
|
||||
));
|
||||
}
|
||||
|
||||
/// This runs on a loop and attempts to accept a connection to pass into the
|
||||
/// handlers that manage client communication. It is very important to note
|
||||
/// that the xev.Completion is shared between the acceptor and other handlers.
|
||||
/// When a client disconnects, only then the completion is freed.
|
||||
fn acceptor(
|
||||
self_: ?*Server,
|
||||
loop: *xev.Loop,
|
||||
c: *xev.Completion,
|
||||
e: xev.Timer.RunError!void,
|
||||
) xev.CallbackAction {
|
||||
const self = self_.?;
|
||||
e catch {
|
||||
log.err("timer error", .{});
|
||||
return .disarm;
|
||||
};
|
||||
|
||||
self.socket.accept(loop, c, Server, self, acceptHandler);
|
||||
|
||||
// We need to create a new completion for the next acceptor since each
|
||||
// TCP connection will need its own if it successfully accepts.
|
||||
const c_a = self.comp_pool.create() catch {
|
||||
log.err("couldn't allocate completion in pool", .{});
|
||||
return .disarm;
|
||||
};
|
||||
|
||||
// We can't rearm because it'll repeat *this* instance of the acceptor
|
||||
// So if the socket fails to accept it won't actually accept anything new
|
||||
self.acceptor.run(loop, c_a, ACCEPTOR_RATE, Server, self, acceptor);
|
||||
return .disarm;
|
||||
}
|
||||
|
||||
/// Accepts a new client connection and starts reading from it until EOF.
|
||||
/// Once an accept handler enters, it queues for a new client connection.
|
||||
/// It essentially recursively calls itself until shutdown.
|
||||
fn acceptHandler(
|
||||
self_: ?*Server,
|
||||
_: *xev.Loop,
|
||||
@ -172,6 +135,14 @@ fn acceptHandler(
|
||||
e: xev.TCP.AcceptError!xev.TCP,
|
||||
) xev.CallbackAction {
|
||||
const self = self_.?;
|
||||
const new_c = self.comp_pool.create() catch {
|
||||
log.err("couldn't allocate completion in pool", .{});
|
||||
return .disarm;
|
||||
};
|
||||
|
||||
// Accept a new client connection now that we have a new completion
|
||||
self.socket.accept(&self.loop, new_c, Server, self, acceptHandler);
|
||||
|
||||
const sock = self.sock_pool.create() catch {
|
||||
log.err("couldn't allocate socket in pool", .{});
|
||||
return .disarm;
|
||||
|
Reference in New Issue
Block a user