Skip to content

Commit e7e5856

Browse files
committed
Proper handling async IO for WIN32
Even given OVERLAPPED, functions like ReadFile/WriteFile still MAY complete before they return. In that case, we should not call GetOverlappedResult, and should respect the numberOfBytes output from the original IO function.
1 parent 61d5df6 commit e7e5856

File tree

4 files changed

+6
-9
lines changed

4 files changed

+6
-9
lines changed

libc/calls/ntspawn.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ static textwindows ssize_t ntspawn_read(intptr_t fh, char *buf, size_t len) {
6868
uint32_t got;
6969
struct NtOverlapped overlap = {.hEvent = CreateEvent(0, 0, 0, 0)};
7070
ok = overlap.hEvent &&
71-
(ReadFile(fh, buf, len, 0, &overlap) ||
71+
(ReadFile(fh, buf, len, &got, &overlap) ||
7272
GetLastError() == kNtErrorIoPending) &&
7373
GetOverlappedResult(fh, &overlap, &got, true);
7474
if (overlap.hEvent)

libc/calls/readwrite-nt.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ sys_readwrite_nt(int fd, void *data, size_t size, ssize_t offset,
9393

9494
// initiate asynchronous i/o operation with win32
9595
struct NtOverlapped overlap = {.hEvent = event, .Pointer = offset};
96-
bool32 ok = ReadOrWriteFile(handle, data, size, 0, &overlap);
96+
uint32_t exchanged = 0;
97+
bool32 ok = ReadOrWriteFile(handle, data, size, &exchanged, &overlap);
9798
if (!ok && GetLastError() == kNtErrorIoPending) {
9899
if (f->flags & _O_NONBLOCK) {
99100
// immediately back out of blocking i/o if non-blocking
@@ -135,11 +136,8 @@ sys_readwrite_nt(int fd, void *data, size_t size, ssize_t offset,
135136
CancelIoEx(handle, &overlap);
136137
}
137138
}
138-
ok = true;
139-
}
140-
uint32_t exchanged = 0;
141-
if (ok)
142139
ok = GetOverlappedResult(handle, &overlap, &exchanged, true);
140+
}
143141
uint32_t io_error = GetLastError();
144142
CloseHandle(event);
145143

libc/calls/winexec.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ textwindows int IsWindowsExecutable(int64_t handle, const char16_t *path) {
8181
BLOCK_SIGNALS;
8282
struct NtOverlapped overlap = {.hEvent = CreateEvent(0, 0, 0, 0)};
8383
ok = overlap.hEvent &&
84-
(ReadFile(handle, buf, 2, 0, &overlap) ||
84+
(ReadFile(handle, buf, 2, &got, &overlap) ||
8585
GetLastError() == kNtErrorIoPending) &&
8686
GetOverlappedResult(handle, &overlap, &got, true);
8787
CloseHandle(overlap.hEvent);

libc/intrin/kprintf.greg.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,7 @@ ABI void klog(const char *b, size_t n) {
362362
struct NtOverlapped overlap = {.hEvent = ev};
363363
ok = !!__imp_WriteFile(h, b, n, 0, &overlap);
364364
if (!ok && __imp_GetLastError() == kNtErrorIoPending)
365-
ok = true;
366-
ok &= !!__imp_GetOverlappedResult(h, &overlap, &wrote, true);
365+
ok = !!__imp_GetOverlappedResult(h, &overlap, &wrote, true);
367366
if (!ok)
368367
__klog_handle = 0;
369368
__imp_CloseHandle(ev);

0 commit comments

Comments
 (0)