1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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);
}
}
}
}
}
|