]> gitweb.ps.run Git - chirp/blob - src/epoll.zig
dunno
[chirp] / src / epoll.zig
1 const std = @import("std");
2 const net = std.net;
3 const posix = std.posix;
4 const linux = std.os.linux;
5 const lmdb = @import("lmdb");
6
7 fn test_lmdb(env: *lmdb.Env) !void {
8     const txn = try env.txn();
9     defer txn.abort();
10
11     const sessions = try txn.dbi("sessions", u64, u64);
12     var cursor = try sessions.cursor();
13
14     var key: u64 = undefined;
15     var user_id_maybe = cursor.get(&key, .First);
16
17     while (user_id_maybe) |user_id| {
18         _ = user_id;
19         user_id_maybe = cursor.get(&key, .Next);
20     }
21 }
22
23 pub fn main() !void {
24     const address = try std.net.Address.parseIp("127.0.0.1", 5882);
25
26     const tpe: u32 = posix.SOCK.STREAM | posix.SOCK.NONBLOCK;
27     const protocol = posix.IPPROTO.TCP;
28     const listener = try posix.socket(address.any.family, tpe, protocol);
29     defer posix.close(listener);
30
31     const BACKLOG = 256;
32
33     try posix.setsockopt(listener, posix.SOL.SOCKET, posix.SO.REUSEADDR, &std.mem.toBytes(@as(c_int, 1)));
34     try posix.bind(listener, &address.any, address.getOsSockLen());
35     try posix.listen(listener, BACKLOG);
36
37     // epoll_create1 takes flags. We aren't using any in these examples
38     const efd = try posix.epoll_create1(0);
39     defer posix.close(efd);
40
41     {
42         // monitor our listening socket
43         var event = linux.epoll_event{ .events = linux.EPOLL.IN, .data = .{ .fd = listener } };
44         try posix.epoll_ctl(efd, linux.EPOLL.CTL_ADD, listener, &event);
45     }
46
47     var env = lmdb.Env.open("db", 1024 * 100);
48     defer env.close();
49
50     var ready_list: [BACKLOG]linux.epoll_event = undefined;
51     while (true) {
52         const ready_count = posix.epoll_wait(efd, &ready_list, -1);
53         for (ready_list[0..ready_count]) |ready| {
54             const ready_socket = ready.data.fd;
55             if (ready_socket == listener) {
56                 const client_socket = try posix.accept(listener, null, null, posix.SOCK.NONBLOCK);
57                 errdefer posix.close(client_socket);
58                 var event = linux.epoll_event{ .events = linux.EPOLL.IN, .data = .{ .fd = client_socket } };
59                 try posix.epoll_ctl(efd, linux.EPOLL.CTL_ADD, client_socket, &event);
60             } else {
61                 var closed = false;
62                 var buf: [4096]u8 = undefined;
63                 const read = posix.read(ready_socket, &buf) catch 0;
64                 if (read == 0) {
65                     closed = true;
66                 } else {
67                     // std.debug.print("[{d}] got: {s}\n", .{ ready_socket, buf[0..read] });
68
69                     try test_lmdb(&env);
70
71                     _ = 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");
72                 }
73
74                 if (closed or ready.events & linux.EPOLL.RDHUP == linux.EPOLL.RDHUP) {
75                     posix.close(ready_socket);
76                 }
77             }
78         }
79     }
80 }