-
Notifications
You must be signed in to change notification settings - Fork 15
parallel: add support to explicitly destroy TLS keys #98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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<Underlying: RawThreadLocalStorage> { | |
|
|
||
| /// Token used to index into the thread local storage. | ||
| public struct Key<Value: AnyObject> { | ||
| fileprivate let key: Underlying.Key | ||
| fileprivate var key: Underlying.Key | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: if
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can revert this change even without that - I call that out in the commit message with an explanation of why I changed this. It's purely for detection purposes. If we say that the user is responsible for knowing when they have invalidated the TLS slot, this can remain a |
||
|
|
||
| /// The thread-local value associated with `self`. | ||
| public var localValue: Value? { | ||
|
|
@@ -176,6 +178,11 @@ public struct TypedThreadLocalStorage<Underlying: RawThreadLocalStorage> { | |
| Key(key: Underlying.makeKey()) | ||
| } | ||
|
|
||
| /// Deallocates a key for type `T`. | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto. |
||
| public static func destroyKey<T: AnyObject>(_ key: inout Key<T>) { | ||
| Underlying.destroyKey(&key.key) | ||
| } | ||
|
|
||
| /// Retrieves the thread-local value for `key`, if it exists. | ||
| public static func get<T: AnyObject>(_ key: Key<T>) -> T? { | ||
| guard let ptr = Underlying.get(for: key.key) else { return nil } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's change |
||
| key.value = 0 | ||
| #endif | ||
| } | ||
|
|
||
| public static func get(for key: Key) -> UnsafeMutableRawPointer? { | ||
| pthread_getspecific(key.value) | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would a better design be for the
Key's destructor to handle cleanup?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
destroyKeyis different from the key destructor - it frees the TLS slot for re-use, it does not handle the cleanup of the TLS key itself, which remains the duty of the TLS destructor.