#Kqueue simple event loop

1 messages · Page 1 of 1 (latest)

merry flare
#

For some reason it handle only the first socket connection

fn echo(stream: std.net.Stream) !void {
    while (true) {
        var buf: [1024]u8 = undefined;
        const n = stream.read(&buf) catch break;
        if (n == 0) break;
        _ = try stream.write(&buf);
    }
}

const ConnectionHandler = struct {
    k_fd: i32,
    server: *std.net.Server,

    pub fn handleConnection(handler: usize) anyerror!void {
        const h: *ConnectionHandler = @ptrFromInt(handler);

        const conn = try h.server.accept();
        defer conn.stream.close();
        while (true) {
            try echo(conn.stream);
        }
    }
};

const KeventCallback = *const fn (handler: usize) anyerror!void;
const KeventData = struct {
    callback: KeventCallback,
    data: usize,
};

pub fn main() !void {
    const address = try std.net.Address.parseIp4("127.0.0.1", 8080);
    var listener = try address.listen(.{
        .reuse_address = true,
    });

    const k_fd = try std.posix.kqueue();

    const conn_handler: ConnectionHandler = .{
        .k_fd = k_fd,
        .server = &listener,
    };

    const e_data: KeventData = .{
        .callback = &ConnectionHandler.handleConnection,
        .data = @intFromPtr(&conn_handler),
    };

    var events: [100]Kevent = undefined;
    const sock_change: Kevent = .{
        .ident = @intCast(listener.stream.handle),
        .filter = std.c.EVFILT_READ,
        .flags = std.c.EV_ADD,
        .fflags = 0,
        .udata = @intFromPtr(&e_data),
        .data = 0,
    };

    const events_to_watch = [_]Kevent{sock_change};

    _ = try std.posix.kevent(k_fd, &events_to_watch, &events, null);

    while (true) {
        for (events) |ev| {
            if (ev.ident != listener.stream.handle) continue;
            const k_data: *KeventData = @ptrFromInt(ev.udata);
            try k_data.callback(k_data.data);
        }
    }
}

Am i doing something wrong, or misunderstanding something ?

lost relic
#

You only call kevent once and not in a/the loop?