85 lines
2.1 KiB
Zig
85 lines
2.1 KiB
Zig
const std = @import("std");
|
|
const posix = std.posix;
|
|
|
|
/// Event signaling using Linux eventfd
|
|
/// Allows efficient cross-thread event notification without polling
|
|
pub const EventFd = struct {
|
|
fd: posix.fd_t,
|
|
|
|
pub const Error = error{
|
|
EventFdCreateFailed,
|
|
};
|
|
|
|
/// Create a new eventfd
|
|
pub fn init() Error!EventFd {
|
|
// EFD_NONBLOCK | EFD_CLOEXEC
|
|
const flags: u32 = 0x800 | 0x80000;
|
|
const fd = std.os.linux.eventfd(0, flags);
|
|
if (@as(isize, @bitCast(fd)) < 0) {
|
|
return error.EventFdCreateFailed;
|
|
}
|
|
return .{ .fd = @intCast(fd) };
|
|
}
|
|
|
|
pub fn deinit(self: *EventFd) void {
|
|
posix.close(self.fd);
|
|
}
|
|
|
|
/// Signal the event (non-blocking)
|
|
pub fn signal(self: *EventFd) void {
|
|
const val: u64 = 1;
|
|
_ = posix.write(self.fd, std.mem.asBytes(&val)) catch {};
|
|
}
|
|
|
|
/// Consume the event (non-blocking, returns true if event was pending)
|
|
pub fn consume(self: *EventFd) bool {
|
|
var val: u64 = undefined;
|
|
const n = posix.read(self.fd, std.mem.asBytes(&val)) catch return false;
|
|
return n == 8;
|
|
}
|
|
|
|
/// Get the file descriptor for polling
|
|
pub fn getFd(self: *EventFd) posix.fd_t {
|
|
return self.fd;
|
|
}
|
|
};
|
|
|
|
/// Global eventfd for denylist reload signaling
|
|
var denylist_event: ?EventFd = null;
|
|
|
|
/// Initialize the global denylist event
|
|
pub fn initDenylistEvent() !void {
|
|
denylist_event = try EventFd.init();
|
|
}
|
|
|
|
/// Deinitialize the global denylist event
|
|
pub fn deinitDenylistEvent() void {
|
|
if (denylist_event) |*ev| {
|
|
ev.deinit();
|
|
denylist_event = null;
|
|
}
|
|
}
|
|
|
|
/// Signal that denylist needs reload
|
|
pub fn signalDenylistReload() void {
|
|
if (denylist_event) |*ev| {
|
|
ev.signal();
|
|
}
|
|
}
|
|
|
|
/// Get the denylist event fd for polling (returns -1 if not initialized)
|
|
pub fn getDenylistEventFd() posix.fd_t {
|
|
if (denylist_event) |*ev| {
|
|
return ev.getFd();
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/// Consume the denylist reload event
|
|
pub fn consumeDenylistReload() bool {
|
|
if (denylist_event) |*ev| {
|
|
return ev.consume();
|
|
}
|
|
return false;
|
|
}
|