Cooperative pool deadlock when calling into an opaque subsystem

No need; I filed the feedback when I read the post a few days ago.

This use pattern with semaphores and GCD is a long established anti-pattern. The Clang static analyzer has been detecting and diagnosing this pattern since Xcode 10, because this pattern has always caused performance problems. Swift concurrency aside, I think occurrences of this should always be considered bugs.

The suggested workaround in this discussion thread to invoke the API from an overcommit queue is the right way to work around these bugs in APIs you don't own (e.g. the continuation + DispatchQueue.global() dance). This works because using the continuation will suspend the task, so the current thread is freed up to perform other work, and dispatch then has the option to create another thread to unblock the work if necessary.

This pattern should absolutely be documented, and perhaps an API should go in the Concurrency library so that there's a standard way to write the workaround. I also agree that runtime diagnostics to surface when this has happened would be extremely valuable.

20 Likes