authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-02 14:30:51-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-02 14:38:11-04:00
log96a6bc57d20cff5171437a483422f53b0231a03d
treedf04aae9da7c7eaf940a2a3c8ba99660627dc9d6
parenta3f55aaf34f0a459c8aec4b35e55ad4534eaca30

modify std.event.Loop to work for windows and macos


1 files changed, 52 insertions(+), 15 deletions(-)

std/event.zig+52-15
......@@ -95,29 +95,56 @@ pub const TcpServer = struct {
9595
9696pub const Loop = struct {
9797 allocator: *mem.Allocator,
98 epollfd: i32,
9998 keep_running: bool,
10099 next_tick_queue: std.atomic.QueueMpsc(promise),
100 os_data: OsData,
101
102 const OsData = switch (builtin.os) {
103 builtin.Os.linux => struct {
104 epollfd: i32,
105 },
106 else => struct {},
107 };
101108
102109 pub const NextTickNode = std.atomic.QueueMpsc(promise).Node;
103110
104111 /// The allocator must be thread-safe because we use it for multiplexing
105112 /// coroutines onto kernel threads.
106113 pub fn init(allocator: *mem.Allocator) !Loop {
107 const epollfd = try std.os.linuxEpollCreate(std.os.linux.EPOLL_CLOEXEC);
108 errdefer std.os.close(epollfd);
109
110 return Loop{
114 var self = Loop{
111115 .keep_running = true,
112116 .allocator = allocator,
113 .epollfd = epollfd,
117 .os_data = undefined,
114118 .next_tick_queue = std.atomic.QueueMpsc(promise).init(),
115119 };
120 try self.initOsData();
121 errdefer self.deinitOsData();
122
123 return self;
116124 }
117125
118126 /// must call stop before deinit
119127 pub fn deinit(self: *Loop) void {
120 std.os.close(self.epollfd);
128 self.deinitOsData();
129 }
130
131 const InitOsDataError = std.os.LinuxEpollCreateError;
132
133 fn initOsData(self: *Loop) InitOsDataError!void {
134 switch (builtin.os) {
135 builtin.Os.linux => {
136 self.os_data.epollfd = try std.os.linuxEpollCreate(std.os.linux.EPOLL_CLOEXEC);
137 errdefer std.os.close(self.os_data.epollfd);
138 },
139 else => {},
140 }
141 }
142
143 fn deinitOsData(self: *Loop) void {
144 switch (builtin.os) {
145 builtin.Os.linux => std.os.close(self.os_data.epollfd),
146 else => {},
147 }
121148 }
122149
123150 pub fn addFd(self: *Loop, fd: i32, prom: promise) !void {
......@@ -125,11 +152,11 @@ pub const Loop = struct {
125152 .events = std.os.linux.EPOLLIN | std.os.linux.EPOLLOUT | std.os.linux.EPOLLET,
126153 .data = std.os.linux.epoll_data{ .ptr = @ptrToInt(prom) },
127154 };
128 try std.os.linuxEpollCtl(self.epollfd, std.os.linux.EPOLL_CTL_ADD, fd, &ev);
155 try std.os.linuxEpollCtl(self.os_data.epollfd, std.os.linux.EPOLL_CTL_ADD, fd, &ev);
129156 }
130157
131158 pub fn removeFd(self: *Loop, fd: i32) void {
132 std.os.linuxEpollCtl(self.epollfd, std.os.linux.EPOLL_CTL_DEL, fd, undefined) catch {};
159 std.os.linuxEpollCtl(self.os_data.epollfd, std.os.linux.EPOLL_CTL_DEL, fd, undefined) catch {};
133160 }
134161 async fn waitFd(self: *Loop, fd: i32) !void {
135162 defer self.removeFd(fd);
......@@ -156,12 +183,22 @@ pub const Loop = struct {
156183 resume node.data;
157184 }
158185 if (!self.keep_running) break;
159 var events: [16]std.os.linux.epoll_event = undefined;
160 const count = std.os.linuxEpollWait(self.epollfd, events[0..], -1);
161 for (events[0..count]) |ev| {
162 const p = @intToPtr(promise, ev.data.ptr);
163 resume p;
164 }
186
187 self.dispatchOsEvents();
188 }
189 }
190
191 fn dispatchOsEvents(self: *Loop) void {
192 switch (builtin.os) {
193 builtin.Os.linux => {
194 var events: [16]std.os.linux.epoll_event = undefined;
195 const count = std.os.linuxEpollWait(self.os_data.epollfd, events[0..], -1);
196 for (events[0..count]) |ev| {
197 const p = @intToPtr(promise, ev.data.ptr);
198 resume p;
199 }
200 },
201 else => {},
165202 }
166203 }
167204};