fn cancelAwaitable(thread: *Thread, awaitable: AwaitableId) bool {
var status = thread.status.load(.monotonic);
while (true) {
if (status.awaitable != awaitable) return false; // thread is working on something else
status = switch (status.cancelation) {
.none => thread.status.cmpxchgWeak(
.{ .cancelation = .none, .awaitable = awaitable },
.{ .cancelation = .canceling, .awaitable = awaitable },
.monotonic,
.monotonic,
) orelse return false,
.parked => thread.status.cmpxchgWeak(
.{ .cancelation = .parked, .awaitable = awaitable },
.{ .cancelation = .canceling, .awaitable = awaitable },
.acquire, // acquire `thread.futex_waiter`
.monotonic,
) orelse {
if (!use_parking_futex and !use_parking_sleep) unreachable;
if (thread.futex_waiter) |futex_waiter| {
parking_futex.removeCanceledWaiter(futex_waiter);
}
if (need_unpark_flag) setUnparkFlag(&thread.unpark_flag);
unpark(&.{if (ParkTid == std.Thread.Id) thread.id else thread.park_tid}, null);
return false;
},
.blocked => thread.status.cmpxchgWeak(
.{ .cancelation = .blocked, .awaitable = awaitable },
.{ .cancelation = .blocked_canceling, .awaitable = awaitable },
.monotonic,
.monotonic,
) orelse return true,
.blocked_alertable => thread.status.cmpxchgWeak(
.{ .cancelation = .blocked_alertable, .awaitable = awaitable },
.{ .cancelation = .blocked_alertable_canceling, .awaitable = awaitable },
.monotonic,
.monotonic,
) orelse {
if (!is_windows) unreachable;
return true;
},
.canceling, .canceled => {
// This can happen when the task start raced with the cancelation, so the thread
// saw the cancelation on the future/group *and* we are trying to signal the
// thread here.
return false;
},
.blocked_canceling => unreachable, // `awaitable` has not been canceled before now
.blocked_alertable_canceling => unreachable, // `awaitable` has not been canceled before now
};
}
}
Cancels
threadif it is working onawaitable.It is possible that
threadgets canceled by this function, but is blocked in a syscall. In that case, the thread may need to be sent a signal to interrupt the call. This function will returntrueto indicate this, in which case the caller must callsignalCanceledSyscall.