This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig standard library. Private Function
Sends a signal to thread if it is still blocked in a syscall (i.e. has not yet observed the cancelation request from cancelAwaitable).
Unfortunately, the signal could arrive before the syscall actually starts, so the interrupt is missed. To handle this, we may need to send multiple signals. As such, if this function returns true, then it should be called again after a short delay to send another signal if the thread is still blocked. For the implementation, Future.waitForCancelWithSignaling and Group.waitForCancelWithSignaling: they use exponential backoff starting at a 1us delay and doubling each call. In practice, it is rare to send more than one signal.
fnsignalCanceledSyscall(thread: *Thread, t: *Threaded, awaitable: AwaitableId) bool {
conststatus = thread.status.load(.monotonic);
if (status.awaitable != awaitable) {
// The thread has moved on and is working on something totally different.returnfalse;
}
// The thread ID and/or handle can be read non-atomically because they never change and were// released by the store that made `thread` available to us.switch (status.cancelation) {
.blocked_canceling => if (std.Thread.use_pthreads) {
returnswitch (std.c.pthread_kill(thread.handle, .IO)) {
0 => true,
else => false,
};
} elseswitch (native_os) {
.linux => {
constpid: posix.pid_t = pid: {
constcached_pid = @atomicLoad(Pid, &t.pid, .monotonic);
if (cached_pid != .unknown) break :pid@backingInt(cached_pid);
constpid = std.os.linux.getpid();
@atomicStore(Pid, &t.pid, @fromBackingInt(@intCast(pid)), .monotonic);
break :pidpid;
};
returnswitch (std.os.linux.tgkill(pid, @bitCast(thread.id), .IO)) {
0 => true,
else => false,
};
},
.windows => {
variosb: windows.IO_STATUS_BLOCK = undefined;
returnswitch (windows.ntdll.NtCancelSynchronousIoFile(thread.handle, null, &iosb)) {
.NOT_FOUND => true, // this might mean the operation hasn't started yet
.SUCCESS => false, // the OS confirmed that our cancelation workedelse => false,
};
},
else => returnfalse,
},
.blocked_alertable_canceling => {
if (!is_windows) unreachable;
returnswitch (windows.ntdll.NtAlertThread(thread.handle)) {
.SUCCESS => true,
else => false,
};
},
else => {
// The thread is working on `awaitable`, but no longer needs signaling (they already// woke up and saw the cancelation).returnfalse;
},
}
}
Sends a signal to
threadif it is still blocked in a syscall (i.e. has not yet observed the cancelation request fromcancelAwaitable).Unfortunately, the signal could arrive before the syscall actually starts, so the interrupt is missed. To handle this, we may need to send multiple signals. As such, if this function returns
true, then it should be called again after a short delay to send another signal if the thread is still blocked. For the implementation,Future.waitForCancelWithSignalingandGroup.waitForCancelWithSignaling: they use exponential backoff starting at a 1us delay and doubling each call. In practice, it is rare to send more than one signal.