Skip to content

Instantly share code, notes, and snippets.

@ipavlidakis
Created July 26, 2023 08:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ipavlidakis/45052ed0265f6858fd82cc8b9c5c1535 to your computer and use it in GitHub Desktop.
Save ipavlidakis/45052ed0265f6858fd82cc8b9c5c1535 to your computer and use it in GitHub Desktop.
//
// Copyright © 2023 Ilias Pavlidakis. All rights reserved.
//
import Foundation
/// Provides thread-safe access to the provided value's storage
struct ThreadSafeValueAccessor<Value> {
/// Describes the access level to a value's storage. Currently supports: .read, .write
enum AccessLevel: Hashable { case read, write }
/// The accessLevels that will be thread-safe when using this instance
private let accessLevels: [AccessLevel]
/// The queue that thread-safe access to the value's storage
private var accessQueue: DispatchQueue
private var _value: Value
var value: Value {
get { readValue() }
set { writeValue(newValue) }
}
init(
_ initialValue: Value,
with accessLevels: [AccessLevel] = [.read, .write],
queueLabel: String = "com.ipavlidakis.thread.safe.value.accessor.\(type(of: Value.self))",
qos: DispatchQoS
) {
_value = initialValue
self.accessLevels = accessLevels
accessQueue = .init(label: queueLabel, qos: qos)
}
private func readValue() -> Value {
guard accessLevels.contains(.read) else {
return _value
}
return accessQueue.sync { return _value }
}
private mutating func writeValue(_ newValue: Value) {
guard accessLevels.contains(.write) else {
_value = newValue
return
}
accessQueue.sync {
_value = newValue
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment