Skip to content

Commit

Permalink
chore: various finalizing cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
Corendos committed Apr 23, 2023
1 parent b341ce9 commit a2f8cc0
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 99 deletions.
60 changes: 32 additions & 28 deletions src/backend/iocp.zig
Original file line number Diff line number Diff line change
Expand Up @@ -332,14 +332,7 @@ pub const Loop = struct {
switch (action) {
.disarm => {},
.rearm => {
// TODO(Corendos): Add a reset function to do that on rearm.
completion.overlapped = .{
.Internal = 0,
.InternalHigh = 0,
.DUMMYUNIONNAME = .{ .Pointer = null },
.hEvent = null,
};
completion.result = null;
completion.reset();
self.start_completion(completion);
},
}
Expand Down Expand Up @@ -478,10 +471,8 @@ pub const Loop = struct {
var opt_len: i32 = @intCast(i32, socket_type_bytes.len);
std.debug.assert(windows.ws2_32.getsockopt(asSocket(v.socket), std.os.SOL.SOCKET, std.os.SO.TYPE, socket_type_bytes, &opt_len) == 0);

// TODO(Corendos): Maybe we should use the same parameter as the listening
// socket.
v.internal_accept_socket = windows.WSASocketW(addr.family, socket_type, 0, null, 0, windows.ws2_32.WSA_FLAG_OVERLAPPED) catch {
break :action .{ .result = .{ .accept = error.Unexpected } };
v.internal_accept_socket = windows.WSASocketW(addr.family, socket_type, 0, null, 0, windows.ws2_32.WSA_FLAG_OVERLAPPED) catch |err| {
break :action .{ .result = .{ .accept = err } };
};
}

Expand All @@ -500,10 +491,13 @@ pub const Loop = struct {
);
if (result != windows.TRUE) {
const err = windows.ws2_32.WSAGetLastError();
break :action switch (err) {
windows.ws2_32.WinsockError.WSA_IO_PENDING => .{ .submitted = {} },
else => .{ .result = .{ .accept = windows.unexpectedWSAError(err) } },
};
switch (err) {
windows.ws2_32.WinsockError.WSA_IO_PENDING => break :action .{ .submitted = {} },
else => {
windows.CloseHandle(v.internal_accept_socket.?);
break :action .{ .result = .{ .accept = windows.unexpectedWSAError(err) } };
},
}
}

break :action .{ .submitted = {} };
Expand All @@ -525,7 +519,7 @@ pub const Loop = struct {
.read => |*v| action: {
self.associate_fd(completion.handle().?) catch unreachable;
var buffer: []u8 = if (v.buffer == .slice) v.buffer.slice else &v.buffer.array;
break :action if (windows.ReadFileW(v.fd, buffer, &completion.overlapped)) |_|
break :action if (windows.exp.ReadFile(v.fd, buffer, &completion.overlapped)) |_|
.{
.submitted = {},
}
Expand All @@ -540,7 +534,7 @@ pub const Loop = struct {
.write => |*v| action: {
self.associate_fd(completion.handle().?) catch unreachable;
var buffer: []const u8 = if (v.buffer == .slice) v.buffer.slice else v.buffer.array.array[0..v.buffer.array.len];
break :action if (windows.WriteFileW(v.fd, buffer, &completion.overlapped)) |_|
break :action if (windows.exp.WriteFile(v.fd, buffer, &completion.overlapped)) |_|
.{
.submitted = {},
}
Expand Down Expand Up @@ -879,15 +873,16 @@ pub const Completion = struct {
var flags: u32 = 0;
const result = windows.ws2_32.WSAGetOverlappedResult(asSocket(v.socket), &self.overlapped, &bytes_transferred, windows.FALSE, &flags);

// TODO(Corendos): maybe we should close the socket in case of error
if (result != windows.TRUE) {
const err = windows.ws2_32.WSAGetLastError();
break :r .{
const r = .{
.accept = switch (err) {
windows.ws2_32.WinsockError.WSA_OPERATION_ABORTED => error.Canceled,
else => windows.unexpectedWSAError(err),
},
};
windows.CloseHandle(v.internal_accept_socket.?);
break :r r;
}

break :r .{ .accept = self.op.accept.internal_accept_socket.? };
Expand Down Expand Up @@ -1010,6 +1005,17 @@ pub const Completion = struct {
.async_wait => .{ .async_wait = {} },
};
}

/// Reset the completion so it can be reused (in case of rearming for example).
pub fn reset(self: *Completion) void {
self.overlapped = .{
.Internal = 0,
.InternalHigh = 0,
.DUMMYUNIONNAME = .{ .Pointer = null },
.hEvent = null,
};
self.result = null;
}
};

pub const OperationType = enum {
Expand Down Expand Up @@ -1159,6 +1165,10 @@ pub const CancelError = error{
};

pub const AcceptError = error{
AddressFamilyNotSupported,
ProcessFdQuotaExceeded,
SystemResources,
ProtocolNotSupported,
Canceled,
Unexpected,
};
Expand Down Expand Up @@ -1619,12 +1629,6 @@ test "iocp: noop" {
try loop.run(.once);
}

fn openTempFile(name: [:0]const u16) !windows.HANDLE {
const result = windows.CreateFile(name, windows.GENERIC_READ | windows.GENERIC_WRITE, 0, null, windows.OPEN_ALWAYS, windows.FILE_FLAG_OVERLAPPED, null);

return result;
}

test "iocp: file IO" {
const testing = std.testing;

Expand All @@ -1633,8 +1637,8 @@ test "iocp: file IO" {

const utf16_file_name = (try windows.sliceToPrefixedFileW("test_watcher_file")).span();

const f_handle = try windows.CreateFile(utf16_file_name, windows.GENERIC_READ | windows.GENERIC_WRITE, 0, null, windows.OPEN_ALWAYS, windows.FILE_FLAG_OVERLAPPED, null);
defer windows.DeleteFileW(utf16_file_name) catch {};
const f_handle = try windows.exp.CreateFile(utf16_file_name, windows.GENERIC_READ | windows.GENERIC_WRITE, 0, null, windows.OPEN_ALWAYS, windows.FILE_FLAG_OVERLAPPED, null);
defer windows.exp.DeleteFile(utf16_file_name) catch {};
defer windows.CloseHandle(f_handle);

// Perform a write and then a read
Expand Down
131 changes: 60 additions & 71 deletions src/windows.zig
Original file line number Diff line number Diff line change
@@ -1,88 +1,77 @@
const std = @import("std");
const windows = std.os.windows;
const kernel32 = windows.kernel32;

pub usingnamespace std.os.windows;

pub const FILE_GENERIC_READ =
windows.STANDARD_RIGHTS_READ |
windows.FILE_READ_DATA |
windows.FILE_READ_ATTRIBUTES |
windows.FILE_READ_EA |
windows.SYNCHRONIZE;
pub const FILE_GENERIC_WRITE =
windows.STANDARD_RIGHTS_WRITE |
windows.FILE_WRITE_DATA |
windows.FILE_WRITE_ATTRIBUTES |
windows.FILE_WRITE_EA |
windows.SYNCHRONIZE;
/// Namespace containing missing utils from std
pub const exp = struct {
pub const CreateFileError = error{} || std.os.UnexpectedError;

pub const CreateFileError = error{} || std.os.UnexpectedError;
pub fn CreateFile(
lpFileName: [*:0]const u16,
dwDesiredAccess: windows.DWORD,
dwShareMode: windows.DWORD,
lpSecurityAttributes: ?*windows.SECURITY_ATTRIBUTES,
dwCreationDisposition: windows.DWORD,
dwFlagsAndAttributes: windows.DWORD,
hTemplateFile: ?windows.HANDLE,
) CreateFileError!windows.HANDLE {
const handle = windows.kernel32.CreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
if (handle == windows.INVALID_HANDLE_VALUE) {
const err = windows.kernel32.GetLastError();
return switch (err) {
else => windows.unexpectedError(err),
};
}

pub fn CreateFile(
lpFileName: [*:0]const u16,
dwDesiredAccess: windows.DWORD,
dwShareMode: windows.DWORD,
lpSecurityAttributes: ?*windows.SECURITY_ATTRIBUTES,
dwCreationDisposition: windows.DWORD,
dwFlagsAndAttributes: windows.DWORD,
hTemplateFile: ?windows.HANDLE,
) CreateFileError!windows.HANDLE {
const handle = windows.kernel32.CreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
if (handle == windows.INVALID_HANDLE_VALUE) {
const err = windows.kernel32.GetLastError();
return switch (err) {
else => windows.unexpectedError(err),
};
return handle;
}

return handle;
}
pub fn ReadFile(
handle: windows.HANDLE,
buffer: []u8,
overlapped: ?*windows.OVERLAPPED,
) windows.ReadFileError!?usize {
var read: windows.DWORD = 0;
const result: windows.BOOL = windows.kernel32.ReadFile(handle, buffer.ptr, @intCast(windows.DWORD, buffer.len), &read, overlapped);
if (result == windows.FALSE) {
const err = windows.kernel32.GetLastError();
return switch (err) {
windows.Win32Error.IO_PENDING => null,
else => windows.unexpectedError(err),
};
}

pub fn ReadFileW(
handle: windows.HANDLE,
buffer: []u8,
overlapped: ?*windows.OVERLAPPED,
) windows.ReadFileError!?usize {
var read: windows.DWORD = 0;
const result: windows.BOOL = kernel32.ReadFile(handle, buffer.ptr, @intCast(windows.DWORD, buffer.len), &read, overlapped);
if (result == windows.FALSE) {
const err = kernel32.GetLastError();
return switch (err) {
windows.Win32Error.IO_PENDING => null,
else => windows.unexpectedError(err),
};
return @intCast(usize, read);
}

return @intCast(usize, read);
}
pub fn WriteFile(
handle: windows.HANDLE,
buffer: []const u8,
overlapped: ?*windows.OVERLAPPED,
) windows.WriteFileError!?usize {
var written: windows.DWORD = 0;
const result: windows.BOOL = windows.kernel32.WriteFile(handle, buffer.ptr, @intCast(windows.DWORD, buffer.len), &written, overlapped);
if (result == windows.FALSE) {
const err = windows.kernel32.GetLastError();
return switch (err) {
windows.Win32Error.IO_PENDING => null,
else => windows.unexpectedError(err),
};
}

pub fn WriteFileW(
handle: windows.HANDLE,
buffer: []const u8,
overlapped: ?*windows.OVERLAPPED,
) windows.WriteFileError!?usize {
var written: windows.DWORD = 0;
const result: windows.BOOL = kernel32.WriteFile(handle, buffer.ptr, @intCast(windows.DWORD, buffer.len), &written, overlapped);
if (result == windows.FALSE) {
const err = kernel32.GetLastError();
return switch (err) {
windows.Win32Error.IO_PENDING => null,
else => windows.unexpectedError(err),
};
return @intCast(usize, written);
}

return @intCast(usize, written);
}
pub const DeleteFileError = error{} || std.os.UnexpectedError;

pub const DeleteFileError = error{} || std.os.UnexpectedError;

pub fn DeleteFileW(name: [*:0]const u16) DeleteFileError!void {
const result: windows.BOOL = kernel32.DeleteFileW(name);
if (result == windows.FALSE) {
const err = kernel32.GetLastError();
return switch (err) {
else => windows.unexpectedError(err),
};
pub fn DeleteFile(name: [*:0]const u16) DeleteFileError!void {
const result: windows.BOOL = windows.kernel32.DeleteFileW(name);
if (result == windows.FALSE) {
const err = windows.kernel32.GetLastError();
return switch (err) {
else => windows.unexpectedError(err),
};
}
}
}
};

0 comments on commit a2f8cc0

Please sign in to comment.