mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 00:35:10 +00:00
modify std.event.Loop to work for windows and macos
This commit is contained in:
parent
a3f55aaf34
commit
96a6bc57d2
@ -95,29 +95,56 @@ pub const TcpServer = struct {
|
||||
|
||||
pub const Loop = struct {
|
||||
allocator: *mem.Allocator,
|
||||
epollfd: i32,
|
||||
keep_running: bool,
|
||||
next_tick_queue: std.atomic.QueueMpsc(promise),
|
||||
os_data: OsData,
|
||||
|
||||
const OsData = switch (builtin.os) {
|
||||
builtin.Os.linux => struct {
|
||||
epollfd: i32,
|
||||
},
|
||||
else => struct {},
|
||||
};
|
||||
|
||||
pub const NextTickNode = std.atomic.QueueMpsc(promise).Node;
|
||||
|
||||
/// The allocator must be thread-safe because we use it for multiplexing
|
||||
/// coroutines onto kernel threads.
|
||||
pub fn init(allocator: *mem.Allocator) !Loop {
|
||||
const epollfd = try std.os.linuxEpollCreate(std.os.linux.EPOLL_CLOEXEC);
|
||||
errdefer std.os.close(epollfd);
|
||||
|
||||
return Loop{
|
||||
var self = Loop{
|
||||
.keep_running = true,
|
||||
.allocator = allocator,
|
||||
.epollfd = epollfd,
|
||||
.os_data = undefined,
|
||||
.next_tick_queue = std.atomic.QueueMpsc(promise).init(),
|
||||
};
|
||||
try self.initOsData();
|
||||
errdefer self.deinitOsData();
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/// must call stop before deinit
|
||||
pub fn deinit(self: *Loop) void {
|
||||
std.os.close(self.epollfd);
|
||||
self.deinitOsData();
|
||||
}
|
||||
|
||||
const InitOsDataError = std.os.LinuxEpollCreateError;
|
||||
|
||||
fn initOsData(self: *Loop) InitOsDataError!void {
|
||||
switch (builtin.os) {
|
||||
builtin.Os.linux => {
|
||||
self.os_data.epollfd = try std.os.linuxEpollCreate(std.os.linux.EPOLL_CLOEXEC);
|
||||
errdefer std.os.close(self.os_data.epollfd);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn deinitOsData(self: *Loop) void {
|
||||
switch (builtin.os) {
|
||||
builtin.Os.linux => std.os.close(self.os_data.epollfd),
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn addFd(self: *Loop, fd: i32, prom: promise) !void {
|
||||
@ -125,11 +152,11 @@ pub const Loop = struct {
|
||||
.events = std.os.linux.EPOLLIN | std.os.linux.EPOLLOUT | std.os.linux.EPOLLET,
|
||||
.data = std.os.linux.epoll_data{ .ptr = @ptrToInt(prom) },
|
||||
};
|
||||
try std.os.linuxEpollCtl(self.epollfd, std.os.linux.EPOLL_CTL_ADD, fd, &ev);
|
||||
try std.os.linuxEpollCtl(self.os_data.epollfd, std.os.linux.EPOLL_CTL_ADD, fd, &ev);
|
||||
}
|
||||
|
||||
pub fn removeFd(self: *Loop, fd: i32) void {
|
||||
std.os.linuxEpollCtl(self.epollfd, std.os.linux.EPOLL_CTL_DEL, fd, undefined) catch {};
|
||||
std.os.linuxEpollCtl(self.os_data.epollfd, std.os.linux.EPOLL_CTL_DEL, fd, undefined) catch {};
|
||||
}
|
||||
async fn waitFd(self: *Loop, fd: i32) !void {
|
||||
defer self.removeFd(fd);
|
||||
@ -156,12 +183,22 @@ pub const Loop = struct {
|
||||
resume node.data;
|
||||
}
|
||||
if (!self.keep_running) break;
|
||||
var events: [16]std.os.linux.epoll_event = undefined;
|
||||
const count = std.os.linuxEpollWait(self.epollfd, events[0..], -1);
|
||||
for (events[0..count]) |ev| {
|
||||
const p = @intToPtr(promise, ev.data.ptr);
|
||||
resume p;
|
||||
}
|
||||
|
||||
self.dispatchOsEvents();
|
||||
}
|
||||
}
|
||||
|
||||
fn dispatchOsEvents(self: *Loop) void {
|
||||
switch (builtin.os) {
|
||||
builtin.Os.linux => {
|
||||
var events: [16]std.os.linux.epoll_event = undefined;
|
||||
const count = std.os.linuxEpollWait(self.os_data.epollfd, events[0..], -1);
|
||||
for (events[0..count]) |ev| {
|
||||
const p = @intToPtr(promise, ev.data.ptr);
|
||||
resume p;
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user