Synchronized
Synchronized copied to clipboard
A Swift generic wrapper type to help enforce thread-safe access to properties.
Synchronized<T>
A Swift genric wrapper type to help enforce thread-safe usage of stored properties.
This is an idea that started with a post on my blog, and I followed up with a discussion about the Locking protocol.
Current Status
- I've been using it some small projects, and find it useful enough to share.
Example Usage
class C {
private let criticalCount = Synchronized<Int>(0)
/// This might be called on any thread, and we want to increment the
/// `criticalCount`, without introducing a race condition.
func incrementOnUnknownThread() {
criticalCount.update { count in
count += 1
}
}
}
Available Locking Strategies
DispatchSemaphoreDispatchQueueNSLockpthread_rwlock_t
Installation
I don't have a Cartfile because it seems silly to add a whole dynamic
.framework to your app just to use this. Instead, I'd recommend just grabbing
the single Synchronized.swift file, and adding that to your project directly.
I did add a Package.swift file for Swift Package Manager, just for fun. Let's
hope Xcode gets better support for that soon!
⚠️ Caveats
- This doesn't fully guarantee thread-safety for reference types, if you hold
a reference to the
Synchronizedresource that escapes the closure, and then access/mutate it. But this at least makes it harder to do that. - This hasn't been thoroughly tested yet, or used in serious production code, but I do think the idea is sound, so more testing and usage would do it good.
Further Ideas (TODO)
- Add more locking strategies
os_unfair_lockpthread_mutex_tdirectly?
- Refine the naming of the
update()anduse()methods`- Some ideas are:
- for the
use()method:read(),with() - for the
update()method:write(),mutate()
- for the
- Some ideas are:
- Further testing, especially performance testing of the various locking strategies
Similar Projects
I didn't know about this when I wrote this initially, but I noticed something similar to this, in PMHTTP, named QueueConfined. But that one doesn't have the ability to change the locking mechanism (it always uses a serial queue).