It's funny because this prompted me searching for alternatives to @reentrant(never)
, and I ended up finding that you can deadlock an actor without it.
Hastily written so please excuse any syntax error, but this will deadlock right?
actor Deadlock {
var task: Task.Handle<Int>?
func getValue() async -> Int {
if task == nil {
task = detachedTask {
return await computeValue()
}
}
return await task!.get()
}
private func computeValue() async -> Int {
return await getValue() + 1
}
}
Technically, only the getValue
member is deadlocked; other parts of the actor not depending on getValue
or computeValue
would still run. In practice it might not make much of a difference.
For reference, the @reentrant(never)
equivalent would look like this:
actor Deadlock {
var value: Int?
@reentrant(never)
func getValue() async -> Int {
if value == nil {
value = await computeValue()
}
return value!
}
private func computeValue() async -> Int {
return await getValue() + 1
}
}