authorgravatar for BarabasGitHub@users.noreply.github.comBas van den Berg <BarabasGitHub@users.noreply.github.com> 2020-09-10 20:20:27+02:00
committergravatar for BarabasGitHub@users.noreply.github.comBas van den Berg <BarabasGitHub@users.noreply.github.com> 2020-09-10 20:20:27+02:00
log127fa8009011e19d552ffdd834c6a607498f1c1e
treecd3895e82a0fd773358faf9f0c45ec38cfd51581
parentf5b9e445aa9d2b344b87d4868f9fbb8021577f55

implement poll for windows with WSAPoll (only available on vista and higher)


4 files changed, 68 insertions(+), 7 deletions(-)

lib/std/os.zig+25-7
...@@ -5208,6 +5208,9 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len...@@ -5208,6 +5208,9 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len
5208}5208}
52095209
5210pub const PollError = error{5210pub const PollError = error{
5211 /// The network subsystem has failed.
5212 NetworkSubsystemFailed,
5213
5211 /// The kernel had no space to allocate file descriptor tables.5214 /// The kernel had no space to allocate file descriptor tables.
5212 SystemResources,5215 SystemResources,
5213} || UnexpectedError;5216} || UnexpectedError;
...@@ -5215,14 +5218,29 @@ pub const PollError = error{...@@ -5215,14 +5218,29 @@ pub const PollError = error{
5215pub fn poll(fds: []pollfd, timeout: i32) PollError!usize {5218pub fn poll(fds: []pollfd, timeout: i32) PollError!usize {
5216 while (true) {5219 while (true) {
5217 const rc = system.poll(fds.ptr, fds.len, timeout);5220 const rc = system.poll(fds.ptr, fds.len, timeout);
5218 switch (errno(rc)) {5221 if (builtin.os.tag == .windows) {
5219 0 => return @intCast(usize, rc),5222 if (rc == windows.ws2_32.SOCKET_ERROR) {
5220 EFAULT => unreachable,5223 switch (windows.ws2_32.WSAGetLastError()) {
5221 EINTR => continue,5224 .WSANOTINITIALISED => unreachable,
5222 EINVAL => unreachable,5225 .WSAENETDOWN => return error.NetworkSubsystemFailed,
5223 ENOMEM => return error.SystemResources,5226 .WSAENOBUFS => return error.SystemResources,
5224 else => |err| return unexpectedErrno(err),5227 // TODO: handle more errors
5228 else => |err| return windows.unexpectedWSAError(err),
5229 }
5230 } else {
5231 return @intCast(usize, rc);
5232 }
5233 } else {
5234 switch (errno(rc)) {
5235 0 => return @intCast(usize, rc),
5236 EFAULT => unreachable,
5237 EINTR => continue,
5238 EINVAL => unreachable,
5239 ENOMEM => return error.SystemResources,
5240 else => |err| return unexpectedErrno(err),
5241 }
5225 }5242 }
5243 unreachable;
5226 }5244 }
5227}5245}
52285246
lib/std/os/bits/windows.zig+13
...@@ -243,6 +243,19 @@ pub const IPPROTO_UDP = ws2_32.IPPROTO_UDP;...@@ -243,6 +243,19 @@ pub const IPPROTO_UDP = ws2_32.IPPROTO_UDP;
243pub const IPPROTO_ICMPV6 = ws2_32.IPPROTO_ICMPV6;243pub const IPPROTO_ICMPV6 = ws2_32.IPPROTO_ICMPV6;
244pub const IPPROTO_RM = ws2_32.IPPROTO_RM;244pub const IPPROTO_RM = ws2_32.IPPROTO_RM;
245245
246pub const pollfd = ws2_32.pollfd;
247
248pub const POLLRDNORM = ws2_32.POLLRDNORM;
249pub const POLLRDBAND = ws2_32.POLLRDBAND;
250pub const POLLIN = ws2_32.POLLIN;
251pub const POLLPRI = ws2_32.POLLPRI;
252pub const POLLWRNORM = ws2_32.POLLWRNORM;
253pub const POLLOUT = ws2_32.POLLOUT;
254pub const POLLWRBAND = ws2_32.POLLWRBAND;
255pub const POLLERR = ws2_32.POLLERR;
256pub const POLLHUP = ws2_32.POLLHUP;
257pub const POLLNVAL = ws2_32.POLLNVAL;
258
246pub const O_RDONLY = 0o0;259pub const O_RDONLY = 0o0;
247pub const O_WRONLY = 0o1;260pub const O_WRONLY = 0o1;
248pub const O_RDWR = 0o2;261pub const O_RDWR = 0o2;
lib/std/os/windows.zig+4
...@@ -1201,6 +1201,10 @@ pub fn recvfrom(s: ws2_32.SOCKET, buf: [*]u8, len: usize, flags: u32, from: ?*ws...@@ -1201,6 +1201,10 @@ pub fn recvfrom(s: ws2_32.SOCKET, buf: [*]u8, len: usize, flags: u32, from: ?*ws
1201 }1201 }
1202}1202}
12031203
1204pub fn poll(fds: [*]ws2_32.pollfd, n: usize, timeout: i32) i32 {
1205 return ws2_32.WSAPoll(fds, @intCast(u32, n), timeout);
1206}
1207
1204pub fn WSAIoctl(1208pub fn WSAIoctl(
1205 s: ws2_32.SOCKET,1209 s: ws2_32.SOCKET,
1206 dwIoControlCode: DWORD,1210 dwIoControlCode: DWORD,
lib/std/os/windows/ws2_32.zig+26
...@@ -234,6 +234,27 @@ pub const WSAMSG = extern struct {...@@ -234,6 +234,27 @@ pub const WSAMSG = extern struct {
234 dwFlags: DWORD,234 dwFlags: DWORD,
235};235};
236236
237pub const pollfd = extern struct {
238 fd: SOCKET,
239 events: SHORT,
240 revents: SHORT,
241};
242
243// Event flag definitions for WSAPoll().
244
245pub const POLLRDNORM = 0x0100;
246pub const POLLRDBAND = 0x0200;
247pub const POLLIN = (POLLRDNORM | POLLRDBAND);
248pub const POLLPRI = 0x0400;
249
250pub const POLLWRNORM = 0x0010;
251pub const POLLOUT = (POLLWRNORM);
252pub const POLLWRBAND = 0x0020;
253
254pub const POLLERR = 0x0001;
255pub const POLLHUP = 0x0002;
256pub const POLLNVAL = 0x0004;
257
237// https://docs.microsoft.com/en-au/windows/win32/winsock/windows-sockets-error-codes-2258// https://docs.microsoft.com/en-au/windows/win32/winsock/windows-sockets-error-codes-2
238pub const WinsockError = extern enum(u16) {259pub const WinsockError = extern enum(u16) {
239 /// Specified event object handle is invalid.260 /// Specified event object handle is invalid.
...@@ -790,6 +811,11 @@ pub extern "ws2_32" fn WSASendTo(...@@ -790,6 +811,11 @@ pub extern "ws2_32" fn WSASendTo(
790 lpOverlapped: ?*WSAOVERLAPPED,811 lpOverlapped: ?*WSAOVERLAPPED,
791 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,812 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
792) callconv(.Stdcall) c_int;813) callconv(.Stdcall) c_int;
814pub extern "ws2_32" fn WSAPoll(
815 fdArray: [*]pollfd,
816 fds: c_ulong,
817 timeout: c_int,
818) callconv(.Stdcall) c_int;
793pub extern "ws2_32" fn getaddrinfo(819pub extern "ws2_32" fn getaddrinfo(
794 pNodeName: [*:0]const u8,820 pNodeName: [*:0]const u8,
795 pServiceName: [*:0]const u8,821 pServiceName: [*:0]const u8,