mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-23 19:10:30 +00:00
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.
This commit is contained in:
parent
61d5df6e6d
commit
e7e5856b83
4 changed files with 6 additions and 9 deletions
|
@ -68,7 +68,7 @@ static textwindows ssize_t ntspawn_read(intptr_t fh, char *buf, size_t len) {
|
|||
uint32_t got;
|
||||
struct NtOverlapped overlap = {.hEvent = CreateEvent(0, 0, 0, 0)};
|
||||
ok = overlap.hEvent &&
|
||||
(ReadFile(fh, buf, len, 0, &overlap) ||
|
||||
(ReadFile(fh, buf, len, &got, &overlap) ||
|
||||
GetLastError() == kNtErrorIoPending) &&
|
||||
GetOverlappedResult(fh, &overlap, &got, true);
|
||||
if (overlap.hEvent)
|
||||
|
|
|
@ -93,7 +93,8 @@ sys_readwrite_nt(int fd, void *data, size_t size, ssize_t offset,
|
|||
|
||||
// initiate asynchronous i/o operation with win32
|
||||
struct NtOverlapped overlap = {.hEvent = event, .Pointer = offset};
|
||||
bool32 ok = ReadOrWriteFile(handle, data, size, 0, &overlap);
|
||||
uint32_t exchanged = 0;
|
||||
bool32 ok = ReadOrWriteFile(handle, data, size, &exchanged, &overlap);
|
||||
if (!ok && GetLastError() == kNtErrorIoPending) {
|
||||
if (f->flags & _O_NONBLOCK) {
|
||||
// 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,
|
|||
CancelIoEx(handle, &overlap);
|
||||
}
|
||||
}
|
||||
ok = true;
|
||||
}
|
||||
uint32_t exchanged = 0;
|
||||
if (ok)
|
||||
ok = GetOverlappedResult(handle, &overlap, &exchanged, true);
|
||||
}
|
||||
uint32_t io_error = GetLastError();
|
||||
CloseHandle(event);
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ textwindows int IsWindowsExecutable(int64_t handle, const char16_t *path) {
|
|||
BLOCK_SIGNALS;
|
||||
struct NtOverlapped overlap = {.hEvent = CreateEvent(0, 0, 0, 0)};
|
||||
ok = overlap.hEvent &&
|
||||
(ReadFile(handle, buf, 2, 0, &overlap) ||
|
||||
(ReadFile(handle, buf, 2, &got, &overlap) ||
|
||||
GetLastError() == kNtErrorIoPending) &&
|
||||
GetOverlappedResult(handle, &overlap, &got, true);
|
||||
CloseHandle(overlap.hEvent);
|
||||
|
|
|
@ -362,8 +362,7 @@ ABI void klog(const char *b, size_t n) {
|
|||
struct NtOverlapped overlap = {.hEvent = ev};
|
||||
ok = !!__imp_WriteFile(h, b, n, 0, &overlap);
|
||||
if (!ok && __imp_GetLastError() == kNtErrorIoPending)
|
||||
ok = true;
|
||||
ok &= !!__imp_GetOverlappedResult(h, &overlap, &wrote, true);
|
||||
ok = !!__imp_GetOverlappedResult(h, &overlap, &wrote, true);
|
||||
if (!ok)
|
||||
__klog_handle = 0;
|
||||
__imp_CloseHandle(ev);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue