Merge pull request #3715 from daurnimator/towards-afd

Misc windows additions+fixes
This commit is contained in:
Andrew Kelley 2019-12-02 16:12:55 -05:00 committed by GitHub
commit b7be57766b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 311 additions and 83 deletions

View File

@ -235,7 +235,7 @@ pub const ChildProcess = struct {
}
fn waitUnwrappedWindows(self: *ChildProcess) !void {
const result = windows.WaitForSingleObject(self.handle, windows.INFINITE);
const result = windows.WaitForSingleObjectEx(self.handle, windows.INFINITE, false);
self.term = @as(SpawnError!Term, x: {
var exit_code: windows.DWORD = undefined;

View File

@ -1,6 +1,7 @@
// The reference for these types and values is Microsoft Windows's ucrt (Universal C RunTime).
usingnamespace @import("../windows/bits.zig");
const ws2_32 = @import("../windows/ws2_32.zig");
pub const fd_t = HANDLE;
pub const pid_t = HANDLE;
@ -163,80 +164,63 @@ pub const F_OK = 0;
pub const AT_REMOVEDIR = 0x200;
pub const in_port_t = u16;
pub const sa_family_t = u16;
pub const sa_family_t = ws2_32.ADDRESS_FAMILY;
pub const socklen_t = u32;
pub const sockaddr = extern struct {
family: sa_family_t,
data: [14]u8,
};
pub const sockaddr_in = extern struct {
family: sa_family_t = AF_INET,
port: in_port_t,
addr: in_addr,
zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
};
pub const sockaddr_in6 = extern struct {
family: sa_family_t = AF_INET6,
port: in_port_t,
flowinfo: u32,
addr: in6_addr,
scope_id: u32,
};
pub const sockaddr = ws2_32.sockaddr;
pub const sockaddr_in = ws2_32.sockaddr_in;
pub const sockaddr_in6 = ws2_32.sockaddr_in6;
pub const sockaddr_un = ws2_32.sockaddr_un;
pub const in6_addr = [16]u8;
pub const in_addr = u32;
pub const sockaddr_un = extern struct {
family: sa_family_t = AF_UNIX,
path: [108]u8,
};
pub const AF_UNSPEC = ws2_32.AF_UNSPEC;
pub const AF_UNIX = ws2_32.AF_UNIX;
pub const AF_INET = ws2_32.AF_INET;
pub const AF_IMPLINK = ws2_32.AF_IMPLINK;
pub const AF_PUP = ws2_32.AF_PUP;
pub const AF_CHAOS = ws2_32.AF_CHAOS;
pub const AF_NS = ws2_32.AF_NS;
pub const AF_IPX = ws2_32.AF_IPX;
pub const AF_ISO = ws2_32.AF_ISO;
pub const AF_OSI = ws2_32.AF_OSI;
pub const AF_ECMA = ws2_32.AF_ECMA;
pub const AF_DATAKIT = ws2_32.AF_DATAKIT;
pub const AF_CCITT = ws2_32.AF_CCITT;
pub const AF_SNA = ws2_32.AF_SNA;
pub const AF_DECnet = ws2_32.AF_DECnet;
pub const AF_DLI = ws2_32.AF_DLI;
pub const AF_LAT = ws2_32.AF_LAT;
pub const AF_HYLINK = ws2_32.AF_HYLINK;
pub const AF_APPLETALK = ws2_32.AF_APPLETALK;
pub const AF_NETBIOS = ws2_32.AF_NETBIOS;
pub const AF_VOICEVIEW = ws2_32.AF_VOICEVIEW;
pub const AF_FIREFOX = ws2_32.AF_FIREFOX;
pub const AF_UNKNOWN1 = ws2_32.AF_UNKNOWN1;
pub const AF_BAN = ws2_32.AF_BAN;
pub const AF_ATM = ws2_32.AF_ATM;
pub const AF_INET6 = ws2_32.AF_INET6;
pub const AF_CLUSTER = ws2_32.AF_CLUSTER;
pub const AF_12844 = ws2_32.AF_12844;
pub const AF_IRDA = ws2_32.AF_IRDA;
pub const AF_NETDES = ws2_32.AF_NETDES;
pub const AF_TCNPROCESS = ws2_32.AF_TCNPROCESS;
pub const AF_TCNMESSAGE = ws2_32.AF_TCNMESSAGE;
pub const AF_ICLFXBM = ws2_32.AF_ICLFXBM;
pub const AF_BTH = ws2_32.AF_BTH;
pub const AF_MAX = ws2_32.AF_MAX;
pub const AF_UNSPEC = 0;
pub const AF_UNIX = 1;
pub const AF_INET = 2;
pub const AF_IMPLINK = 3;
pub const AF_PUP = 4;
pub const AF_CHAOS = 5;
pub const AF_NS = 6;
pub const AF_IPX = AF_NS;
pub const AF_ISO = 7;
pub const AF_OSI = AF_ISO;
pub const AF_ECMA = 8;
pub const AF_DATAKIT = 9;
pub const AF_CCITT = 10;
pub const AF_SNA = 11;
pub const AF_DECnet = 12;
pub const AF_DLI = 13;
pub const AF_LAT = 14;
pub const AF_HYLINK = 15;
pub const AF_APPLETALK = 16;
pub const AF_NETBIOS = 17;
pub const AF_VOICEVIEW = 18;
pub const AF_FIREFOX = 19;
pub const AF_UNKNOWN1 = 20;
pub const AF_BAN = 21;
pub const AF_ATM = 22;
pub const AF_INET6 = 23;
pub const AF_CLUSTER = 24;
pub const AF_12844 = 25;
pub const AF_IRDA = 26;
pub const AF_NETDES = 28;
pub const AF_TCNPROCESS = 29;
pub const AF_TCNMESSAGE = 30;
pub const AF_ICLFXBM = 31;
pub const AF_BTH = 32;
pub const AF_MAX = 33;
pub const SOCK_STREAM = ws2_32.SOCK_STREAM;
pub const SOCK_DGRAM = ws2_32.SOCK_DGRAM;
pub const SOCK_RAW = ws2_32.SOCK_RAW;
pub const SOCK_RDM = ws2_32.SOCK_RDM;
pub const SOCK_SEQPACKET = ws2_32.SOCK_SEQPACKET;
pub const SOCK_STREAM = 1;
pub const SOCK_DGRAM = 2;
pub const SOCK_RAW = 3;
pub const SOCK_RDM = 4;
pub const SOCK_SEQPACKET = 5;
pub const IPPROTO_ICMP = 1;
pub const IPPROTO_IGMP = 2;
pub const BTHPROTO_RFCOMM = 3;
pub const IPPROTO_TCP = 6;
pub const IPPROTO_UDP = 17;
pub const IPPROTO_ICMPV6 = 58;
pub const IPPROTO_RM = 113;
pub const IPPROTO_ICMP = ws2_32.IPPROTO_ICMP;
pub const IPPROTO_IGMP = ws2_32.IPPROTO_IGMP;
pub const BTHPROTO_RFCOMM = ws2_32.BTHPROTO_RFCOMM;
pub const IPPROTO_TCP = ws2_32.IPPROTO_TCP;
pub const IPPROTO_UDP = ws2_32.IPPROTO_UDP;
pub const IPPROTO_ICMPV6 = ws2_32.IPPROTO_ICMPV6;
pub const IPPROTO_RM = ws2_32.IPPROTO_RM;

View File

@ -97,6 +97,22 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C
}
}
pub fn CreateEventEx(attributes: ?*SECURITY_ATTRIBUTES, name: []const u8, flags: DWORD, desired_access: DWORD) !HANDLE {
const nameW = try sliceToPrefixedFileW(name);
return CreateEventExW(attributes, &nameW, flags, desired_access);
}
pub fn CreateEventExW(attributes: ?*SECURITY_ATTRIBUTES, nameW: [*:0]const u16, flags: DWORD, desired_access: DWORD) !HANDLE {
const handle = kernel32.CreateEventExW(attributes, nameW, flags, desired_access);
if (handle) |h| {
return h;
} else {
switch (kernel32.GetLastError()) {
else => |err| return unexpectedError(err),
}
}
}
pub fn DeviceIoControl(
h: HANDLE,
ioControlCode: DWORD,
@ -116,6 +132,7 @@ pub fn DeviceIoControl(
overlapped,
) == 0) {
switch (kernel32.GetLastError()) {
ERROR.IO_PENDING => if (overlapped == null) unreachable,
else => |err| return unexpectedError(err),
}
}
@ -124,9 +141,9 @@ pub fn DeviceIoControl(
pub fn GetOverlappedResult(h: HANDLE, overlapped: *OVERLAPPED, wait: bool) !DWORD {
var bytes: DWORD = undefined;
if (kernel32.GetOverlappedResult(h, overlapped, &bytes, wait) == 0) {
if (kernel32.GetOverlappedResult(h, overlapped, &bytes, @boolToInt(wait)) == 0) {
switch (kernel32.GetLastError()) {
ERROR_IO_INCOMPLETE => if (!wait) return error.WouldBlock else unreachable,
ERROR.IO_INCOMPLETE => if (!wait) return error.WouldBlock else unreachable,
else => |err| return unexpectedError(err),
}
}
@ -171,8 +188,8 @@ pub const WaitForSingleObjectError = error{
Unexpected,
};
pub fn WaitForSingleObject(handle: HANDLE, milliseconds: DWORD) WaitForSingleObjectError!void {
switch (kernel32.WaitForSingleObject(handle, milliseconds)) {
pub fn WaitForSingleObjectEx(handle: HANDLE, milliseconds: DWORD, alertable: bool) WaitForSingleObjectError!void {
switch (kernel32.WaitForSingleObjectEx(handle, milliseconds, @boolToInt(alertable))) {
WAIT_ABANDONED => return error.WaitAbandoned,
WAIT_OBJECT_0 => return,
WAIT_TIMEOUT => return error.WaitTimeOut,
@ -183,6 +200,34 @@ pub fn WaitForSingleObject(handle: HANDLE, milliseconds: DWORD) WaitForSingleObj
}
}
pub fn WaitForMultipleObjectsEx(handles: []const HANDLE, waitAll: bool, milliseconds: DWORD, alertable: bool) !u32 {
assert(handles.len < MAXIMUM_WAIT_OBJECTS);
const nCount: DWORD = @intCast(DWORD, handles.len);
switch (kernel32.WaitForMultipleObjectsEx(
nCount,
handles.ptr,
@boolToInt(waitAll),
milliseconds,
@boolToInt(alertable),
)) {
WAIT_OBJECT_0...WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS => |n| {
const handle_index = n - WAIT_OBJECT_0;
assert(handle_index < nCount);
return handle_index;
},
WAIT_ABANDONED_0...WAIT_ABANDONED_0 + MAXIMUM_WAIT_OBJECTS => |n| {
const handle_index = n - WAIT_ABANDONED_0;
assert(handle_index < nCount);
return error.WaitAbandoned;
},
WAIT_TIMEOUT => return error.WaitTimeOut,
WAIT_FAILED => switch (kernel32.GetLastError()) {
else => |err| return unexpectedError(err),
},
else => return error.Unexpected,
}
}
pub const FindFirstFileError = error{
FileNotFound,
InvalidUtf8,
@ -647,13 +692,23 @@ pub fn WSASocketW(
return rc;
}
pub fn closesocket(s: ws2_32.SOCKET) !void {
switch (ws2_32.closesocket(s)) {
0 => {},
ws2_32.SOCKET_ERROR => switch (ws2_32.WSAGetLastError()) {
else => |err| return unexpectedWSAError(err),
},
else => unreachable,
}
}
pub fn WSAIoctl(
s: ws2_32.SOCKET,
dwIoControlCode: DWORD,
inBuffer: ?[]const u8,
outBuffer: []u8,
overlapped: ?*ws2_32.WSAOVERLAPPED,
completionRoutine: ?*ws2_32.WSAOVERLAPPED_COMPLETION_ROUTINE,
completionRoutine: ?ws2_32.WSAOVERLAPPED_COMPLETION_ROUTINE,
) !DWORD {
var bytes: DWORD = undefined;
switch (ws2_32.WSAIoctl(

View File

@ -19,7 +19,6 @@ pub const STD_OUTPUT_HANDLE = maxInt(DWORD) - 11 + 1;
/// The standard error device. Initially, this is the active console screen buffer, CONOUT$.
pub const STD_ERROR_HANDLE = maxInt(DWORD) - 12 + 1;
pub const SHORT = c_short;
pub const BOOL = c_int;
pub const BOOLEAN = BYTE;
pub const BYTE = u8;
@ -54,6 +53,8 @@ pub const UNICODE = false;
pub const WCHAR = u16;
pub const WORD = u16;
pub const LARGE_INTEGER = i64;
pub const USHORT = u16;
pub const SHORT = i16;
pub const ULONG = u32;
pub const LONG = i32;
pub const ULONGLONG = u64;
@ -236,7 +237,11 @@ pub const FILE_NAME_INFORMATION = extern struct {
};
pub const IO_STATUS_BLOCK = extern struct {
Status: usize,
// "DUMMYUNIONNAME" expands to "u"
u: extern union {
Status: NTSTATUS,
Pointer: ?*c_void,
},
Information: ULONG_PTR,
};
@ -489,6 +494,13 @@ pub const FILE_ATTRIBUTE_SYSTEM = 0x4;
pub const FILE_ATTRIBUTE_TEMPORARY = 0x100;
pub const FILE_ATTRIBUTE_VIRTUAL = 0x10000;
// flags for CreateEvent
pub const CREATE_EVENT_INITIAL_SET = 0x00000002;
pub const CREATE_EVENT_MANUAL_RESET = 0x00000001;
pub const EVENT_ALL_ACCESS = 0x1F0003;
pub const EVENT_MODIFY_STATE = 0x0002;
pub const PROCESS_INFORMATION = extern struct {
hProcess: HANDLE,
hThread: HANDLE,
@ -534,7 +546,10 @@ pub const STARTF_USESTDHANDLES = 0x00000100;
pub const INFINITE = 4294967295;
pub const MAXIMUM_WAIT_OBJECTS = 64;
pub const WAIT_ABANDONED = 0x00000080;
pub const WAIT_ABANDONED_0 = WAIT_ABANDONED + 0;
pub const WAIT_OBJECT_0 = 0x00000000;
pub const WAIT_TIMEOUT = 0x00000102;
pub const WAIT_FAILED = 0xFFFFFFFF;

View File

@ -9,6 +9,13 @@ pub extern "kernel32" stdcallcc fn CloseHandle(hObject: HANDLE) BOOL;
pub extern "kernel32" stdcallcc fn CreateDirectoryW(lpPathName: [*]const u16, lpSecurityAttributes: ?*SECURITY_ATTRIBUTES) BOOL;
pub extern "kernel32" stdcallcc fn CreateEventExW(
lpEventAttributes: ?*SECURITY_ATTRIBUTES,
lpName: [*:0]const u16,
dwFlags: DWORD,
dwDesiredAccess: DWORD,
) ?HANDLE;
pub extern "kernel32" stdcallcc fn CreateFileW(
lpFileName: [*]const u16, // TODO null terminated pointer type
dwDesiredAccess: DWORD,
@ -52,7 +59,7 @@ pub extern "kernel32" stdcallcc fn DeviceIoControl(
nInBufferSize: DWORD,
lpOutBuffer: ?LPVOID,
nOutBufferSize: DWORD,
lpBytesReturned: LPDWORD,
lpBytesReturned: ?*DWORD,
lpOverlapped: ?*OVERLAPPED,
) BOOL;
@ -205,6 +212,18 @@ pub extern "kernel32" stdcallcc fn TlsFree(dwTlsIndex: DWORD) BOOL;
pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) DWORD;
pub extern "kernel32" stdcallcc fn WaitForSingleObjectEx(hHandle: HANDLE, dwMilliseconds: DWORD, bAlertable: BOOL) DWORD;
pub extern "kernel32" stdcallcc fn WaitForMultipleObjects(nCount: DWORD, lpHandle: [*]const HANDLE, bWaitAll:BOOL, dwMilliseconds: DWORD) DWORD;
pub extern "kernel32" stdcallcc fn WaitForMultipleObjectsEx(
nCount: DWORD,
lpHandle: [*]const HANDLE,
bWaitAll:BOOL,
dwMilliseconds: DWORD,
bAlertable: BOOL,
) DWORD;
pub extern "kernel32" stdcallcc fn WriteFile(
in_hFile: HANDLE,
in_lpBuffer: [*]const u8,

View File

@ -24,8 +24,8 @@ pub extern "NtDll" stdcallcc fn NtCreateFile(
pub extern "NtDll" stdcallcc fn NtDeviceIoControlFile(
FileHandle: HANDLE,
Event: ?HANDLE,
ApcRoutine: ?*IO_APC_ROUTINE,
ApcContext: usize,
ApcRoutine: ?IO_APC_ROUTINE,
ApcContext: ?*c_void,
IoStatusBlock: *IO_STATUS_BLOCK,
IoControlCode: ULONG,
InputBuffer: ?*const c_void,

View File

@ -11,8 +11,13 @@ pub const ABANDONED_WAIT_0 = 0x00000080;
pub const ABANDONED_WAIT_63 = 0x000000BF;
pub const USER_APC = 0x000000C0;
pub const ALERTED = 0x00000101;
/// The given Timeout interval expired.
pub const TIMEOUT = 0x00000102;
/// The operation that was requested is pending completion.
pub const PENDING = 0x00000103;
pub const REPARSE = 0x00000104;
pub const MORE_ENTRIES = 0x00000105;
pub const NOT_ALL_ASSIGNED = 0x00000106;
@ -128,6 +133,8 @@ pub const GUARD_PAGE_VIOLATION = 0x80000001;
pub const DATATYPE_MISALIGNMENT = 0x80000002;
pub const BREAKPOINT = 0x80000003;
pub const SINGLE_STEP = 0x80000004;
/// The data was too large to fit into the specified buffer.
pub const BUFFER_OVERFLOW = 0x80000005;
pub const NO_MORE_FILES = 0x80000006;
pub const WAKE_SYSTEM_DEBUGGER = 0x80000007;

View File

@ -108,6 +108,103 @@ pub const WSAOVERLAPPED = extern struct {
pub const WSAOVERLAPPED_COMPLETION_ROUTINE = extern fn (dwError: DWORD, cbTransferred: DWORD, lpOverlapped: *WSAOVERLAPPED, dwFlags: DWORD) void;
pub const ADDRESS_FAMILY = u16;
// Microsoft use the signed c_int for this, but it should never be negative
const socklen_t = u32;
pub const AF_UNSPEC = 0;
pub const AF_UNIX = 1;
pub const AF_INET = 2;
pub const AF_IMPLINK = 3;
pub const AF_PUP = 4;
pub const AF_CHAOS = 5;
pub const AF_NS = 6;
pub const AF_IPX = AF_NS;
pub const AF_ISO = 7;
pub const AF_OSI = AF_ISO;
pub const AF_ECMA = 8;
pub const AF_DATAKIT = 9;
pub const AF_CCITT = 10;
pub const AF_SNA = 11;
pub const AF_DECnet = 12;
pub const AF_DLI = 13;
pub const AF_LAT = 14;
pub const AF_HYLINK = 15;
pub const AF_APPLETALK = 16;
pub const AF_NETBIOS = 17;
pub const AF_VOICEVIEW = 18;
pub const AF_FIREFOX = 19;
pub const AF_UNKNOWN1 = 20;
pub const AF_BAN = 21;
pub const AF_ATM = 22;
pub const AF_INET6 = 23;
pub const AF_CLUSTER = 24;
pub const AF_12844 = 25;
pub const AF_IRDA = 26;
pub const AF_NETDES = 28;
pub const AF_TCNPROCESS = 29;
pub const AF_TCNMESSAGE = 30;
pub const AF_ICLFXBM = 31;
pub const AF_BTH = 32;
pub const AF_MAX = 33;
pub const SOCK_STREAM = 1;
pub const SOCK_DGRAM = 2;
pub const SOCK_RAW = 3;
pub const SOCK_RDM = 4;
pub const SOCK_SEQPACKET = 5;
pub const IPPROTO_ICMP = 1;
pub const IPPROTO_IGMP = 2;
pub const BTHPROTO_RFCOMM = 3;
pub const IPPROTO_TCP = 6;
pub const IPPROTO_UDP = 17;
pub const IPPROTO_ICMPV6 = 58;
pub const IPPROTO_RM = 113;
pub const sockaddr = extern struct {
family: ADDRESS_FAMILY,
data: [14]u8,
};
/// IPv4 socket address
pub const sockaddr_in = extern struct {
family: ADDRESS_FAMILY = AF_INET,
port: USHORT,
addr: u32,
zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
};
/// IPv6 socket address
pub const sockaddr_in6 = extern struct {
family: ADDRESS_FAMILY = AF_INET6,
port: USHORT,
flowinfo: u32,
addr: [16]u8,
scope_id: u32,
};
/// UNIX domain socket address
pub const sockaddr_un = extern struct {
family: ADDRESS_FAMILY = AF_UNIX,
path: [108]u8,
};
pub const WSABUF = extern struct {
len: ULONG,
buf: [*]u8,
};
pub const WSAMSG = extern struct {
name: *const sockaddr,
namelen: INT,
lpBuffers: [*]WSABUF,
dwBufferCount: DWORD,
Control: WSABUF,
dwFlags: DWORD,
};
pub const WSA_INVALID_HANDLE = 6;
pub const WSA_NOT_ENOUGH_MEMORY = 8;
pub const WSA_INVALID_PARAMETER = 87;
@ -240,6 +337,7 @@ pub extern "ws2_32" stdcallcc fn WSASocketW(
g: GROUP,
dwFlags: DWORD,
) SOCKET;
pub extern "ws2_32" stdcallcc fn closesocket(s: SOCKET) c_int;
pub extern "ws2_32" stdcallcc fn WSAIoctl(
s: SOCKET,
dwIoControlCode: DWORD,
@ -249,5 +347,55 @@ pub extern "ws2_32" stdcallcc fn WSAIoctl(
cbOutBuffer: DWORD,
lpcbBytesReturned: LPDWORD,
lpOverlapped: ?*WSAOVERLAPPED,
lpCompletionRoutine: ?*WSAOVERLAPPED_COMPLETION_ROUTINE,
lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
) c_int;
pub extern "ws2_32" stdcallcc fn accept(
s: SOCKET,
addr: ?*sockaddr,
addrlen: socklen_t,
) SOCKET;
pub extern "ws2_32" stdcallcc fn connect(
s: SOCKET,
name: *const sockaddr,
namelen: socklen_t,
) c_int;
pub extern "ws2_32" stdcallcc fn WSARecv(
s: SOCKET,
lpBuffers: [*]const WSABUF,
dwBufferCount: DWORD,
lpNumberOfBytesRecvd: ?*DWORD,
lpFlags: *DWORD,
lpOverlapped: ?*WSAOVERLAPPED,
lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
) c_int;
pub extern "ws2_32" stdcallcc fn WSARecvFrom(
s: SOCKET,
lpBuffers: [*]const WSABUF,
dwBufferCount: DWORD,
lpNumberOfBytesRecvd: ?*DWORD,
lpFlags: *DWORD,
lpFrom: ?*sockaddr,
lpFromlen: socklen_t,
lpOverlapped: ?*WSAOVERLAPPED,
lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
) c_int;
pub extern "ws2_32" stdcallcc fn WSASend(
s: SOCKET,
lpBuffers: [*]WSABUF,
dwBufferCount: DWORD,
lpNumberOfBytesSent: ?*DWORD,
dwFlags: DWORD,
lpOverlapped: ?*WSAOVERLAPPED,
lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
) c_int;
pub extern "ws2_32" stdcallcc fn WSASendTo(
s: SOCKET,
lpBuffers: [*]WSABUF,
dwBufferCount: DWORD,
lpNumberOfBytesSent: ?*DWORD,
dwFlags: DWORD,
lpTo: ?*const sockaddr,
iTolen: socklen_t,
lpOverlapped: ?*WSAOVERLAPPED,
lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
) c_int;

View File

@ -99,7 +99,7 @@ pub const Thread = struct {
os.munmap(self.data.memory);
},
.windows => {
windows.WaitForSingleObject(self.data.handle, windows.INFINITE) catch unreachable;
windows.WaitForSingleObjectEx(self.data.handle, windows.INFINITE, false) catch unreachable;
windows.CloseHandle(self.data.handle);
windows.HeapFree(self.data.heap_handle, 0, self.data.alloc_start);
},