Skip to content

Commit

Permalink
windows: handles can't have multiple completion keys
Browse files Browse the repository at this point in the history
This kinda sucks, but oh well ...
  • Loading branch information
Cloudef committed Aug 29, 2024
1 parent 48c66c2 commit 9161f2a
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 10 deletions.
28 changes: 20 additions & 8 deletions src/aio/Windows.zig
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const INVALID_SOCKET = win_sock.INVALID_SOCKET;
const threading = win32.system.threading;

const IoContext = struct {
overlapped: io.OVERLAPPED = undefined,
overlapped: io.OVERLAPPED = std.mem.zeroes(io.OVERLAPPED),

// needs to be cleaned up
owned: union(enum) {
Expand Down Expand Up @@ -127,6 +127,20 @@ fn iocpDrainThread(self: *@This()) void {
var key: Iocp.Key = undefined;
var maybe_ovl: ?*io.OVERLAPPED = null;
const res = io.GetQueuedCompletionStatus(self.iocp.port, &transferred, @ptrCast(&key), &maybe_ovl, INFINITE);
if (res != 1 and maybe_ovl == null) {
break;
}

const id: u16 = switch (key.type) {
.shutdown,
.event_source,
.child_exit => key.id,
.overlapped => blk: {
const parent: *IoContext = @fieldParentPtr("overlapped", maybe_ovl.?);
break :blk @intCast((@intFromPtr(parent) - @intFromPtr(self.ovls.ptr)) / @sizeOf(IoContext));
}
};

if (res == 1) {
switch (key.type) {
.shutdown => break,
Expand All @@ -139,7 +153,7 @@ fn iocpDrainThread(self: *@This()) void {
win32.system.system_services.JOB_OBJECT_MSG_EXIT_PROCESS, win32.system.system_services.JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS => {},
else => continue,
}
const op = &self.uringlator.ops.nodes[key.id].used.child_exit;
const op = &self.uringlator.ops.nodes[id].used.child_exit;
if (op.out_term) |term| {
var code: u32 = undefined;
if (win32.system.threading.GetExitCodeProcess(op.child, &code) == 0) {
Expand All @@ -149,14 +163,12 @@ fn iocpDrainThread(self: *@This()) void {
}
}
},
.overlapped => self.ovls[key.id].res = transferred,
.overlapped => self.ovls[id].res = transferred,
}
self.uringlator.finish(key.id, error.Success);
} else if (maybe_ovl) |_| {
std.debug.assert(key.type != .shutdown);
self.uringlator.finish(key.id, werr(0));
self.uringlator.finish(id, error.Success);
} else {
break;
std.debug.assert(key.type != .shutdown);
self.uringlator.finish(id, werr(0));
}
}
}
Expand Down
11 changes: 9 additions & 2 deletions src/aio/posix/windows.zig
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ pub const Iocp = struct {
child_exit,
overlapped,
},
// The ID is only used for custom events, for CreateIoCompletionPort assocations its useless,
// as it prevents from having multiple keys for a single handle:
// > Use the CompletionKey parameter to help your application track which I/O operations have completed.
// > This value is not used by CreateIoCompletionPort for functional control; rather, it is attached to
// > the file handle specified in the FileHandle parameter at the time of association with an I/O completion port.
// > This completion key should be unique for each file handle, and it accompanies the file handle throughout the
// > internal completion queuing process.
id: u16,
_: @Type(.{ .Int = .{ .bits = @bitSizeOf(usize) - @bitSizeOf(u16) * 2, .signedness = .unsigned } }) = undefined,
};
Expand Down Expand Up @@ -80,8 +87,8 @@ pub const Iocp = struct {
self.* = undefined;
}

pub fn associateHandle(self: *@This(), id: u16, handle: HANDLE) !void {
const key: Key = .{ .type = .overlapped, .id = id };
pub fn associateHandle(self: *@This(), _: u16, handle: HANDLE) !void {
const key: Key = .{ .type = .overlapped, .id = undefined };
const res = io.CreateIoCompletionPort(handle, self.port, @bitCast(key), 0);
if (res == null or res.? == INVALID_HANDLE) {
// ignore 87 as it may mean that we just re-registered the handle
Expand Down

0 comments on commit 9161f2a

Please sign in to comment.