diff --git a/Sources/PenguinParallel/ConcurrencyPlatform.swift b/Sources/PenguinParallel/ConcurrencyPlatform.swift index 1209c4b3..28e18e83 100644 --- a/Sources/PenguinParallel/ConcurrencyPlatform.swift +++ b/Sources/PenguinParallel/ConcurrencyPlatform.swift @@ -146,6 +146,8 @@ public protocol RawThreadLocalStorage { /// Makes a new key; the returned key should be used for the entire process lifetime. static func makeKey() -> Key + /// Invalidates a previously constructed key, freeing resources + static func destroyKey(_ key: inout Key) /// Retrieves the raw pointer associated with the given key. static func get(for key: Key) -> UnsafeMutableRawPointer? /// Sets the raw pointer associated with the given key. @@ -158,7 +160,7 @@ public struct TypedThreadLocalStorage { /// Token used to index into the thread local storage. public struct Key { - fileprivate let key: Underlying.Key + fileprivate var key: Underlying.Key /// The thread-local value associated with `self`. public var localValue: Value? { @@ -176,6 +178,11 @@ public struct TypedThreadLocalStorage { Key(key: Underlying.makeKey()) } + /// Deallocates a key for type `T`. + public static func destroyKey(_ key: inout Key) { + Underlying.destroyKey(&key.key) + } + /// Retrieves the thread-local value for `key`, if it exists. public static func get(_ key: Key) -> T? { guard let ptr = Underlying.get(for: key.key) else { return nil } diff --git a/Sources/PenguinParallel/ThreadLocalStorage.swift b/Sources/PenguinParallel/ThreadLocalStorage.swift index a2f6c117..cd768918 100644 --- a/Sources/PenguinParallel/ThreadLocalStorage.swift +++ b/Sources/PenguinParallel/ThreadLocalStorage.swift @@ -59,6 +59,15 @@ public struct PosixThreadLocalStorage: RawThreadLocalStorage { Key() } + public static func destroyKey(_ key: inout Key) { + #if os(Windows) + fatalError("Unimplemented!") + #else + pthread_key_delete(key.value) + key.value = 0 + #endif + } + public static func get(for key: Key) -> UnsafeMutableRawPointer? { pthread_getspecific(key.value) }