An tool for managing actor reentrancy.
This package exposes two types: AsyncGate and AsyncRecursiveGate. These allow you to define asynchronous critical sections. Only one task can enter a critical section at a time. Unlike a traditional lock, you can safely make async calls while these gates are held.
The intended use-case for these is managing actor reentrancy.
Some other concurrency packages you might find useful are Queue and Semaphore. Gate is an independent, but extremely similar package.
Swift Package Manager:
dependencies: [
.package(url: "https://github.com/mattmassicotte/TaskGate", branch: "main")
]Gates are very intentionally non-Sendable. The purpose of a gate is to control tasks running concurrently within a single actor, and making them non-Sendable allows the compiler will help enforce that concept.
Note that trying to acquire an already-gated AsyncGate will deadlock your actor.
import TaskGate
actor MyActor {
var value = 42
let gate = AsyncGate()
let recursiveGate = AsyncRecursiveGate()
func hasCriticalSections() async {
// no matter how many tasks call this method,
// only one will be able to execute at a time
await gate.withGate {
self.value = await otherObject.getValue()
}
}
func hasCriticalSectionsBlock() async {
await recursiveGate.withGate {
// acquiring this multiple times within the same task is safe
await recursiveGate.withGate {
self.value = await otherObject.getValue()
}
}
}
}Both of these gate types support priority escalation propagation to help avoid priority inversions. However, the API required to do this was introduced with SE-0462, which is only available in the 26 OSes and later.
It is important to note that gates cannot be used from a non-async context. Actually doing this would require some trickery, as they both only have async interfaces. But, if you find a way, perhaps via ObjC bridging, you should expect a crash.
I would love to hear from you! Issues or pull requests work great. Both a Matrix space and Discord are also available for live help, but I have a strong bias towards answering in the form of documentation.
I prefer collaboration, and would love to find ways to work together if you have a similar project.
I prefer indentation with tabs for improved accessibility. But, I'd rather you use the system you want and make a PR than hesitate because of whitespace.
By participating in this project you agree to abide by the Contributor Code of Conduct.