X-Git-Url: https://gitweb.ps.run/chirp/blobdiff_plain/c1543f56be31c2d071db75dd7f146e1b5e0de4fe..8ce4f0b76cab1963cd0a8ad55bf5b30b9eae917f:/src/epoll.zig diff --git a/src/epoll.zig b/src/epoll.zig new file mode 100644 index 0000000..afca339 --- /dev/null +++ b/src/epoll.zig @@ -0,0 +1,80 @@ +const std = @import("std"); +const net = std.net; +const posix = std.posix; +const linux = std.os.linux; +const lmdb = @import("lmdb"); + +fn test_lmdb(env: *lmdb.Env) !void { + const txn = try env.txn(); + defer txn.abort(); + + const sessions = try txn.dbi("sessions", u64, u64); + var cursor = try sessions.cursor(); + + var key: u64 = undefined; + var user_id_maybe = cursor.get(&key, .First); + + while (user_id_maybe) |user_id| { + _ = user_id; + user_id_maybe = cursor.get(&key, .Next); + } +} + +pub fn main() !void { + const address = try std.net.Address.parseIp("127.0.0.1", 5882); + + const tpe: u32 = posix.SOCK.STREAM | posix.SOCK.NONBLOCK; + const protocol = posix.IPPROTO.TCP; + const listener = try posix.socket(address.any.family, tpe, protocol); + defer posix.close(listener); + + const BACKLOG = 256; + + try posix.setsockopt(listener, posix.SOL.SOCKET, posix.SO.REUSEADDR, &std.mem.toBytes(@as(c_int, 1))); + try posix.bind(listener, &address.any, address.getOsSockLen()); + try posix.listen(listener, BACKLOG); + + // epoll_create1 takes flags. We aren't using any in these examples + const efd = try posix.epoll_create1(0); + defer posix.close(efd); + + { + // monitor our listening socket + var event = linux.epoll_event{ .events = linux.EPOLL.IN, .data = .{ .fd = listener } }; + try posix.epoll_ctl(efd, linux.EPOLL.CTL_ADD, listener, &event); + } + + var env = lmdb.Env.open("db", 1024 * 100); + defer env.close(); + + var ready_list: [BACKLOG]linux.epoll_event = undefined; + while (true) { + const ready_count = posix.epoll_wait(efd, &ready_list, -1); + for (ready_list[0..ready_count]) |ready| { + const ready_socket = ready.data.fd; + if (ready_socket == listener) { + const client_socket = try posix.accept(listener, null, null, posix.SOCK.NONBLOCK); + errdefer posix.close(client_socket); + var event = linux.epoll_event{ .events = linux.EPOLL.IN, .data = .{ .fd = client_socket } }; + try posix.epoll_ctl(efd, linux.EPOLL.CTL_ADD, client_socket, &event); + } else { + var closed = false; + var buf: [4096]u8 = undefined; + const read = posix.read(ready_socket, &buf) catch 0; + if (read == 0) { + closed = true; + } else { + // std.debug.print("[{d}] got: {s}\n", .{ ready_socket, buf[0..read] }); + + try test_lmdb(&env); + + _ = try posix.write(ready_socket, "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: 5\r\n\r\nabcde"); + } + + if (closed or ready.events & linux.EPOLL.RDHUP == linux.EPOLL.RDHUP) { + posix.close(ready_socket); + } + } + } + } +}