Add thread safety for fonts cache via read-write lock in MTFontManager

This commit is contained in:
Andrew Lebedev
2024-11-20 17:57:37 +01:00
parent 71da5ae960
commit 1dbbaddbff
2 changed files with 61 additions and 2 deletions

View File

@@ -22,9 +22,10 @@ public class MTFontManager {
}
public init() { }
@RWLocked
var nameToFontMap = [String: MTFont]()
public func font(withName name:String, size:CGFloat) -> MTFont? {
var f = self.nameToFontMap[name]
if f == nil {

View File

@@ -0,0 +1,58 @@
import Foundation
final class RWLock {
init() {
pthread_rwlock_init(&lock, nil)
}
deinit {
pthread_rwlock_destroy(&lock)
}
func read<T>(_ block: () -> T) -> T {
pthread_rwlock_rdlock(&lock)
defer { pthread_rwlock_unlock(&lock) }
return block()
}
func readWrite<T>(_ block: () -> T) -> T {
pthread_rwlock_wrlock(&lock)
defer { pthread_rwlock_unlock(&lock) }
return block()
}
private var lock = pthread_rwlock_t()
}
@propertyWrapper
struct RWLocked<T> {
init(wrappedValue: T) {
value = wrappedValue
}
var wrappedValue: T {
get {
lock.read {
value
}
}
set {
lock.readWrite {
value = newValue
}
}
}
@discardableResult
mutating func readWrite(_ block: (inout T) -> Void) -> (oldValue: T, newValue: T) {
lock.readWrite {
let old = value
block(&value)
return (old, value)
}
}
private var value: T
private let lock = RWLock()
}