diff --git a/README.md b/README.md index 12ce987..e4bb838 100644 --- a/README.md +++ b/README.md @@ -15,35 +15,106 @@ Project is tested on zig version 0.14.0-dev.32+4aa15440c ```zig const std = @import("std"); const aio = @import("aio"); -const log = std.log.scoped(.aio_immediate); +const coro = @import("coro"); +const log = std.log.scoped(.coro_aio); -pub fn main() !void { - var f = try std.fs.cwd().openFile("flake.nix", .{}); - defer f.close(); - var buf: [4096]u8 = undefined; +pub const aio_options: aio.Options = .{ + .debug = false, // set to true to enable debug logs +}; + +pub const coro_options: coro.Options = .{ + .debug = false, // set to true to enable debug logs +}; + +pub const std_options: std.Options = .{ + .log_level = .debug, +}; + +const Yield = enum { + server_ready, +}; + +fn server(client_task: coro.Task) !void { + var socket: std.posix.socket_t = undefined; + try coro.io.single(aio.Socket{ + .domain = std.posix.AF.INET, + .flags = std.posix.SOCK.STREAM | std.posix.SOCK.CLOEXEC, + .protocol = std.posix.IPPROTO.TCP, + .out_socket = &socket, + }); + + const address = std.net.Address.initIp4(.{ 0, 0, 0, 0 }, 1327); + try std.posix.setsockopt(socket, std.posix.SOL.SOCKET, std.posix.SO.REUSEADDR, &std.mem.toBytes(@as(c_int, 1))); + try std.posix.setsockopt(socket, std.posix.SOL.SOCKET, std.posix.SO.REUSEPORT, &std.mem.toBytes(@as(c_int, 1))); + try std.posix.bind(socket, &address.any, address.getOsSockLen()); + try std.posix.listen(socket, 128); + + coro.wakeupFromState(client_task, Yield.server_ready, .wait); + + var client_sock: std.posix.socket_t = undefined; + try coro.io.single(aio.Accept{ .socket = socket, .out_socket = &client_sock }); + + var buf: [1024]u8 = undefined; var len: usize = 0; + try coro.io.multi(.{ + aio.Send{ .socket = client_sock, .buffer = "hey ", .link = .soft }, + aio.Send{ .socket = client_sock, .buffer = "I'm doing multiple IO ops at once ", .link = .soft }, + aio.Send{ .socket = client_sock, .buffer = "how cool is that? ", .link = .soft }, + aio.Recv{ .socket = client_sock, .buffer = &buf, .out_read = &len }, + }); - var f2 = try std.fs.cwd().openFile("build.zig.zon", .{}); - defer f2.close(); - var buf2: [4096]u8 = undefined; - var len2: usize = 0; - - const num_errors = try aio.complete(.{ - aio.Read{ - .file = f, - .buffer = &buf, - .out_read = &len, - }, - aio.Read{ - .file = f2, - .buffer = &buf2, - .out_read = &len2, - }, + log.warn("got reply from client: {s}", .{buf[0..len]}); + try coro.io.multi(.{ + aio.Send{ .socket = client_sock, .buffer = "ok bye", .link = .soft }, + aio.CloseSocket{ .socket = client_sock, .link = .soft }, + aio.CloseSocket{ .socket = socket }, }); +} - log.info("{s}", .{buf[0..len]}); - log.info("{s}", .{buf2[0..len2]}); - log.info("{}", .{num_errors}); +fn client() !void { + var socket: std.posix.socket_t = undefined; + try coro.io.single(aio.Socket{ + .domain = std.posix.AF.INET, + .flags = std.posix.SOCK.STREAM | std.posix.SOCK.CLOEXEC, + .protocol = std.posix.IPPROTO.TCP, + .out_socket = &socket, + }); + + coro.yield(Yield.server_ready); + + const address = std.net.Address.initIp4(.{ 127, 0, 0, 1 }, 1327); + try coro.io.single(aio.Connect{ + .socket = socket, + .addr = &address.any, + .addrlen = address.getOsSockLen(), + }); + + while (true) { + var buf: [1024]u8 = undefined; + var len: usize = 0; + try coro.io.single(aio.Recv{ .socket = socket, .buffer = &buf, .out_read = &len }); + log.warn("got reply from server: {s}", .{buf[0..len]}); + if (std.mem.indexOf(u8, buf[0..len], "how cool is that?")) |_| break; + } + + try coro.io.single(aio.Send{ .socket = socket, .buffer = "dude, I don't care" }); + + var buf: [1024]u8 = undefined; + var len: usize = 0; + try coro.io.single(aio.Recv{ .socket = socket, .buffer = &buf, .out_read = &len }); + log.warn("got final words from server: {s}", .{buf[0..len]}); +} + +pub fn main() !void { + // var mem: [4096 * 1024]u8 = undefined; + // var fba = std.heap.FixedBufferAllocator.init(&mem); + var gpa: std.heap.GeneralPurposeAllocator(.{}) = .{}; + defer _ = gpa.deinit(); + var scheduler = try coro.Scheduler.init(gpa.allocator(), .{}); + defer scheduler.deinit(); + const client_task = try scheduler.spawn(client, .{}, .{}); + _ = try scheduler.spawn(server, .{client_task}, .{}); + try scheduler.run(); } ``` diff --git a/flake.nix b/flake.nix index c08c5f9..660eac7 100644 --- a/flake.nix +++ b/flake.nix @@ -68,7 +68,7 @@ ## Example ```zig - $(cat examples/aio_immediate.zig) + $(cat examples/coro.zig) ``` ## Perf