diff --git a/Sources/SwiftMath/MathRender/MTFontManager.swift b/Sources/SwiftMath/MathRender/MTFontManager.swift index 059fe0e..71f42cc 100644 --- a/Sources/SwiftMath/MathRender/MTFontManager.swift +++ b/Sources/SwiftMath/MathRender/MTFontManager.swift @@ -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 { diff --git a/Sources/SwiftMath/MathRender/RWLock.swift b/Sources/SwiftMath/MathRender/RWLock.swift new file mode 100644 index 0000000..ccca397 --- /dev/null +++ b/Sources/SwiftMath/MathRender/RWLock.swift @@ -0,0 +1,58 @@ +import Foundation + +final class RWLock { + init() { + pthread_rwlock_init(&lock, nil) + } + + deinit { + pthread_rwlock_destroy(&lock) + } + + func read(_ block: () -> T) -> T { + pthread_rwlock_rdlock(&lock) + defer { pthread_rwlock_unlock(&lock) } + return block() + } + + func readWrite(_ block: () -> T) -> T { + pthread_rwlock_wrlock(&lock) + defer { pthread_rwlock_unlock(&lock) } + return block() + } + + private var lock = pthread_rwlock_t() +} + +@propertyWrapper +struct RWLocked { + 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() +} +