DispatchSemaphore freeze

I'm calling the following function in a SwiftUI View modifier in Xcode 16.1:

nonisolated function f -> CGFloat {
    let semaphore = DispatchSemaphore(value: 0)
    var a: CGFloat = 0

    DispatchQueue.main.async {
        a = ...
        semaphore.signal()
    }

    semaphore.wait()
    return a
}

The app freezes, and code in the main queue is never executed.

Answered by DTS Engineer in 811685022

Right. That’s because you’re deadlocking the main thread:

  • Your f() function can’t return until someone signals the semaphore.

  • The semaphore can’t be signalled until the f() function returns and the main thread has a chance to service DispatchQueue.main.

I’m not sure what you’re trying to do with a semaphore but it’s almost always the wrong tool to reach for. If you can explain more about the problem you’re trying to solve, I should be able to get you heading in the right direction.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Right. That’s because you’re deadlocking the main thread:

  • Your f() function can’t return until someone signals the semaphore.

  • The semaphore can’t be signalled until the f() function returns and the main thread has a chance to service DispatchQueue.main.

I’m not sure what you’re trying to do with a semaphore but it’s almost always the wrong tool to reach for. If you can explain more about the problem you’re trying to solve, I should be able to get you heading in the right direction.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

The alignmentGuide modifier is @preconcurrency nonisolated. In Swift 6, I had to call a nonisolated function to calculate alignment, in which a certain @MainActor property was needed. That's why I tried to use a semaphore. I have switched back to Swift 5, since AVFoundation is not ready for Swift 6. The problem here is solved by removing nonisolated and semaphore. We may handle it after switching to Swift 6 in the future. Thanks.

DispatchSemaphore freeze
 
 
Q