-
-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
aio: multishot operations #7
Comments
How it could work: fn acceptCallback(context: *anyopaque, socket: std.posix.socket_t, addr: std.posix.addrinfo) !void {
// cancel from inside a callback
return error.Canceled;
}
var id: aio.Id = undefined;
try io.single(aio.AcceptMultishot{ .callback = acceptCallback, .context = arg, .out_id = &id });
// cancel from outside the callback
io.single(aio.Cancel{ .id = id }); |
I've been thinking about this and the callbacks isn't good general strategy. I think having callbacks for more specialized cases is still good, but for general case I see too many problems, especially when I'm braindumping something like: const aio.MultiRecv {
buffers: aio.BufferSet, // .{ .id = <registered buffers id>, .set = <pointer to bitset marking modified buffers> }
// 0 == wait for all buffers to be filled
// this waits at least n completitions, but more
// buffers might be completed when the operation finishes
wait_at_least_n_completions: u16 = 0,
}; Which would also map very well to io_uring registered buffers. |
New braindump, since i think the idea above goes bit too far away from the io_uring api: var id: aio.Id = undefined;
try coro.single(.multishot_recv, .{ .ring = &msg_ring, .out_id = &id });
defer coro.single(.cancel, .{ .id = id }) catch @panic("welp");
while (true) {
// new op that can be used for non multishot stuff as well
try coro.single(.select, .{ .ids = &.{ id } });
// or maybe:
try coro.select(.{
aio.op(.wait, .{ .id = id }, .unlinked),
// could have wait for other id here or some other op
});
// ^ you want to avoid using select on recv and recv likes unless it's MSG.PEEK though as you could lose the data
// I like aio.select / coro.select more myself, as it seems more general, but idk yet which approach I'll take
var iter = msg_ring.iterator();
while (iter.next()) |entry| {
if (entry.id != id) continue;
process_packet(entry.buffer);
entry.release(); // buffer is free to be reused again
}
} |
I've been playing with multishot operations a bit. They don't really fit very well the zig-aio model and the benefits don't seem to impress me yet, but I feel like I may have to work with bigger buffers. |
Seems like my results were skewed by the fact I was doing all communication in one process in my testing, multishot performs better when communication happens in separate processes, I presume this also would map to communication over network as well. Anyhow, I continue working out what kind of approach I should take here. I still favor |
It's possible to have multishot operations that take a callback parameter. These are important for repeating timers and socket accept loops. Should not need any special interface, but there might be some lifetime shenanigans that has to be taken in account.
The text was updated successfully, but these errors were encountered: