From ff0bbc3f961f5702ffb835863f29bd00e7ea1a4c Mon Sep 17 00:00:00 2001 From: Francis Bouvier Date: Wed, 9 Oct 2024 01:21:24 +0200 Subject: [PATCH] server: simplify Send I/O Signed-off-by: Francis Bouvier --- src/server.zig | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/src/server.zig b/src/server.zig index fd5cf8fd..0cbae978 100644 --- a/src/server.zig +++ b/src/server.zig @@ -290,47 +290,40 @@ pub const Ctx = struct { // I/O Send // -------- +// NOTE: to allow concurrent send we create each time a dedicated context +// (with its own completion), allocated on the heap. +// After the send (on the sendCbk) the dedicated context will be destroy +// and the msg slice will be free. const Send = struct { ctx: *Ctx, - buf: []const u8, + msg: []const u8, + completion: Completion = undefined, - fn init(ctx: *Ctx, msg: []const u8) !struct { - ctx: *Send, - completion: *Completion, - } { - // NOTE: it seems we can't use the same completion for concurrent - // recv and timeout operations, that's why we create a new completion here - const completion = try ctx.alloc().create(Completion); - // NOTE: to handle concurrent calls we create each time a new context - // If no concurrent calls where required we could just use the main Ctx + fn init(ctx: *Ctx, msg: []const u8) !*Send { const sd = try ctx.alloc().create(Send); - sd.* = .{ - .ctx = ctx, - .buf = msg, - }; - return .{ .ctx = sd, .completion = completion }; + sd.* = .{ .ctx = ctx, .msg = msg }; + return sd; } - fn deinit(self: *Send, completion: *Completion) void { - self.ctx.alloc().destroy(completion); - self.ctx.alloc().free(self.buf); + fn deinit(self: *Send) void { + self.ctx.alloc().free(self.msg); self.ctx.alloc().destroy(self); } - fn asyncCbk(self: *Send, completion: *Completion, result: SendError!usize) void { + fn asyncCbk(self: *Send, _: *Completion, result: SendError!usize) void { const size = result catch |err| { self.ctx.err = err; return; }; std.log.debug("send async {d} bytes", .{size}); - self.deinit(completion); + self.deinit(); } }; pub fn sendAsync(ctx: *Ctx, msg: []const u8) !void { const sd = try Send.init(ctx, msg); - ctx.loop.io.send(*Send, sd.ctx, Send.asyncCbk, sd.completion, ctx.conn_socket, msg); + ctx.loop.io.send(*Send, sd, Send.asyncCbk, &sd.completion, ctx.conn_socket, msg); } pub fn sendSync(ctx: *Ctx, msg: []const u8) !void {