Skip to content

Commit

Permalink
iocp process watcher: instead of setting limits on the job, compare PIDs
Browse files Browse the repository at this point in the history
  • Loading branch information
kcbanner committed Oct 31, 2023
1 parent d71ddeb commit 908155e
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 32 deletions.
1 change: 0 additions & 1 deletion src/backend/iocp.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1366,7 +1366,6 @@ pub const TimerTrigger = enum {
};

pub const JobObjectError = error{
UnknownMessageType,
Unexpected,
};

Expand Down
47 changes: 16 additions & 31 deletions src/watcher/process.zig
Original file line number Diff line number Diff line change
Expand Up @@ -234,28 +234,11 @@ fn ProcessIocp(comptime xev: type) type {
const job = try windows.exp.CreateJobObject(null, null);
errdefer _ = windows.kernel32.CloseHandle(job);

// Setting this limit information is required so that we only get process exit
// notifications for this process - without it we would get notifications for
// all of its child processes as well.

var extended_limit_information = std.mem.zeroInit(windows.exp.JOBOBJECT_EXTENDED_LIMIT_INFORMATION, .{
.BasicLimitInformation = std.mem.zeroInit(windows.exp.JOBOBJECT_BASIC_LIMIT_INFORMATION, .{
.LimitFlags = windows.exp.JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK,
}),
});

try windows.exp.SetInformationJobObject(
job,
.JobObjectExtendedLimitInformation,
&extended_limit_information,
@sizeOf(@TypeOf(extended_limit_information)),
);

try windows.exp.AssignProcessToJobObject(job, dup_process);

return .{
.process = dup_process,
.job = job,
.process = dup_process,
};
}

Expand Down Expand Up @@ -313,27 +296,29 @@ fn ProcessIocp(comptime xev: type) type {
});
},
.message => |message| {
switch (message.type) {
const result_inner = switch (message.type) {
.JOB_OBJECT_MSG_EXIT_PROCESS,
.JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS,
=> {
// Don't need to check the message value (PID) as we've
// specified JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK
=> b: {
const process: windows.HANDLE = @ptrCast(c_inner.op.job_object.userdata);
const pid = windows.exp.kernel32.GetProcessId(process);
if (pid == 0) break :b WaitError.Unexpected;
if (message.value != pid) return .rearm;

var exit_code: windows.DWORD = undefined;
const process: windows.HANDLE = @ptrCast(c_inner.op.job_object.userdata);
const has_code = windows.kernel32.GetExitCodeProcess(process, &exit_code) != 0;
if (!has_code) std.log.warn("unable to get exit code for process={}", .{windows.kernel32.GetLastError()});

return @call(.always_inline, cb, .{
common.userdataValue(Userdata, ud),
l_inner,
c_inner,
if (has_code) exit_code else WaitError.Unexpected,
});
break :b if (has_code) exit_code else WaitError.Unexpected;
},
else => return .rearm,
}
};

return @call(.always_inline, cb, .{
common.userdataValue(Userdata, ud),
l_inner,
c_inner,
result_inner
});
},
}
} else |err| {
Expand Down
1 change: 1 addition & 0 deletions src/windows.zig
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ pub const exp = struct {
};

pub const kernel32 = struct {
pub extern "kernel32" fn GetProcessId(Process: windows.HANDLE) callconv(windows.WINAPI) windows.DWORD;
pub extern "kernel32" fn CreateJobObjectA(lpSecurityAttributes: ?*windows.SECURITY_ATTRIBUTES, lpName: ?windows.LPCSTR) callconv(windows.WINAPI) windows.HANDLE;
pub extern "kernel32" fn AssignProcessToJobObject(hJob: windows.HANDLE, hProcess: windows.HANDLE) callconv(windows.WINAPI) windows.BOOL;
pub extern "kernel32" fn SetInformationJobObject(
Expand Down

0 comments on commit 908155e

Please sign in to comment.