protocol PoaExecutor
Swift
protocol PoaExecutor : AnyObject, Sendable
A serial execution context that is a thread with its own event loop
rather than a DispatchQueue.
.main and .queue cover everything GCD owns, but they cannot express the
case they are most wanted for: a thread that blocks in someone else's
wait — a GLFW/X11 pump, an epoll loop, a game loop — and that owns state
which may only be touched from that thread. GCD cannot pin a serial queue
to a chosen thread (only .main is pinned, and draining it means the loop
can never block), so such a loop can neither be a hop target nor be woken by
one.
Conforming types supply the two things the C DispatchExecutor needs:
final class RenderLoop: PoaExecutor {
func post(_ work: @escaping @Sendable () -> Void) {
queue.append(work) // drained once per loop iteration
wakeTheLoop() // must unblock the loop's wait
}
var isRunningOnExecutor: Bool { Thread.current === loopThread }
}
post must wake the loop. The ring fires and forgets: nothing else will
tell the loop that work is waiting, so a post that only enqueues leaves
the servant unrun until the loop happens to wake for its own reasons — on an
idle process, never.
The loop must be serial and must drain in FIFO order, for the same
reason .queue demands a serial queue: a shared-memory session matches
replies by ring slot order.
isRunningOnExecutor keeps invoke_sync from posting to a loop it is
already on, which would wait for a drain that cannot happen until it
returns.
nprpc_swift/Sources/NPRPC/Poa.swift:143
Properties
var isRunningOnExecutor: Bool { get }
True when the calling thread is the loop's own.
nprpc_swift/Sources/NPRPC/Poa.swift:147
Methods
func post(_ work: @escaping @Sendable () -> Void)
Enqueue work on the loop and wake it.
nprpc_swift/Sources/NPRPC/Poa.swift:145