DispatchQueue SerialExecutor isolation check is not consistent on Darwin

Okey so this actually is "just" that queue.async{} doesn't set any executor tracking and these assertions are expected and "as designed" tbh. The precondition APIs work with Swift's concurrency model -- so they check tasks and the thread local executor; if there is none -- and there is none here because the queue.async just never sets any such information -- Swift has no idea about it, and thus asserts.

The main actor happens to work because the fallback on "we assume main actor is main thread", which does not require dispatch to do anything. (This assumption is actually true only on 80% of cases as there can be runtimes where the thread serving the main actor and "main queue" is NOT the "main thread", but this is a rare case).

For such assertions to work there must be a TASK that is enqueued on a custom executor that is such queue, and in that run task the precondition is then used and would work.

We can improve on this, and here's a draft: [SerialExecutor] PoC: Allow a SerialExecutor to check its own tracking for isolation checks by ktoso · Pull Request #71172 · apple/swift · GitHub

however rolling this out will need both a swift evolution proposal, and special work for backdeployment.

Keep an eye for evolution proposals and that patch, but as it stands today this is as-designed in 5.10.

5 Likes