Last active
July 2, 2024 13:27
-
-
Save tetsu-koba/4e8674b9fd89281b480b9a81ee06fa52 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const std = @import("std"); | |
const os = std.os; | |
const log = std.log; | |
const time = std.time; | |
const MAX_EVENT = 5; | |
const READ_BUFSIZE = 64 * 1024; | |
const WRITE_BUFSIZE = 64 * 1024; | |
fn createSignalfd() !os.fd_t { | |
var mask = os.empty_sigset; | |
os.linux.sigaddset(&mask, os.linux.SIG.INT); | |
os.linux.sigaddset(&mask, os.linux.SIG.TERM); | |
os.linux.sigaddset(&mask, os.linux.SIG.USR1); | |
os.linux.sigaddset(&mask, os.linux.SIG.USR2); | |
os.sigprocmask(os.linux.SIG.BLOCK, &mask, null); | |
return try os.signalfd(-1, &mask, os.linux.SFD.CLOEXEC); | |
} | |
fn writeFull(fd: os.fd_t, buf: []u8) os.WriteError!void { | |
var written: usize = 0; | |
var n: usize = 0; | |
while (written < buf.len) { | |
n = try os.write(fd, buf[written..]); | |
written += n; | |
} | |
} | |
const filter_op = *const fn (rbuf: []u8, wbuf: []u8) usize; | |
fn filterLoop(f: filter_op, timeout: i32, verbose0: bool) !void { | |
var verbose = verbose0; | |
var running = true; | |
var read_buffer: [READ_BUFSIZE]u8 = .{}; | |
var write_buffer: [WRITE_BUFSIZE]u8 = .{}; | |
const epoll_fd = try os.epoll_create1(os.linux.EPOLL.CLOEXEC); | |
defer os.close(epoll_fd); | |
var read_event = os.linux.epoll_event{ | |
.events = os.linux.EPOLL.IN, | |
.data = os.linux.epoll_data{ .fd = os.linux.STDIN_FILENO }, | |
}; | |
try os.epoll_ctl(epoll_fd, os.linux.EPOLL.CTL_ADD, read_event.data.fd, &read_event); | |
const signal_fd = try createSignalfd(); | |
defer os.close(signal_fd); | |
var signal_event = os.linux.epoll_event{ | |
.events = os.linux.EPOLL.IN, | |
.data = os.linux.epoll_data{ .fd = signal_fd }, | |
}; | |
try os.epoll_ctl(epoll_fd, os.linux.EPOLL.CTL_ADD, signal_event.data.fd, &signal_event); | |
while (running) { | |
var events: [MAX_EVENT]os.linux.epoll_event = .{}; | |
const event_count = os.epoll_wait(epoll_fd, events[0..], timeout); | |
if (event_count == 0) { | |
log.info("{d}:timeout", .{time.milliTimestamp()}); | |
continue; | |
} | |
for (events[0..event_count]) |ev| { | |
if (ev.data.fd == read_event.data.fd) { | |
const bytes_read = try os.read(ev.data.fd, read_buffer[0..]); | |
if (verbose) { | |
log.info("{d}:bytes_read={d}", .{ time.milliTimestamp(), bytes_read }); | |
} | |
if (bytes_read == 0) { | |
running = false; | |
} else { | |
const n = f(read_buffer[0..bytes_read], write_buffer[0..]); | |
if (n < 0) { | |
running = false; | |
} | |
try writeFull(os.linux.STDOUT_FILENO, write_buffer[0..n]); | |
} | |
} else if (ev.data.fd == signal_event.data.fd) { | |
var buf: [@sizeOf(os.linux.signalfd_siginfo)]u8 align(8) = undefined; | |
if (buf.len != try os.read(signal_event.data.fd, &buf)) { | |
return os.ReadError.ReadError; | |
} | |
const info = @ptrCast(*os.linux.signalfd_siginfo, &buf); | |
switch (info.signo) { | |
os.linux.SIG.INT => { | |
log.info("{d}:Got SIGINT", .{time.milliTimestamp()}); | |
running = false; | |
}, | |
os.linux.SIG.TERM => { | |
log.info("{d}:Got SIGTERM", .{time.milliTimestamp()}); | |
running = false; | |
}, | |
os.linux.SIG.USR1 => { | |
log.info("{d}:Set verbose=false", .{time.milliTimestamp()}); | |
verbose = false; | |
}, | |
os.linux.SIG.USR2 => { | |
log.info("{d}:Set verbose=true", .{time.milliTimestamp()}); | |
verbose = true; | |
}, | |
else => unreachable, | |
} | |
} else { | |
unreachable; | |
} | |
} | |
} | |
} | |
fn nopFilter(rbuf: []u8, wbuf: []u8) usize { | |
// Just copy now, replace this to do something great | |
@memcpy(wbuf, rbuf); | |
return rbuf.len; | |
} | |
pub fn main() !void { | |
// TODO: get parameters from command line options | |
const timeout = 10 * 1000; | |
const verbose = true; | |
try filterLoop(nopFilter, timeout, verbose); | |
} |
Help yourself. This sample program was written at the age of zig 0.10.
Help yourself. This sample program was written at the age of zig 0.10.
savage ....
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
does not compile...
(base) user@user-System-Product-Name:
/Desktop/redis_stuff/realtimeDB$ zig build-exe epoll.zig/Desktop/redis_stuff/realtimeDB$epoll.zig:80:30: error: expected 1 argument, found 2
const info = @ptrCast(*os.linux.signalfd_siginfo, &buf);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(base) user@user-System-Product-Name: