Safe Haskell | None |
---|---|
Language | Haskell2010 |
A perilous implementation of thread-local storage for Haskell. This module uses a fair amount of GHC internals to enable performing lookups of context for any threads that are alive. Caution should be taken for consumers of this module to not retain ThreadId references indefinitely, as that could delay cleanup of thread-local state.
Thread-local contexts have the following semantics:
- A value
attach
ed to aThreadId
will remain alive at least as long as theThreadId
. - A value may be detached from a
ThreadId
viadetach
by the library consumer without detriment. - No guarantees are made about when a value will be garbage-collected
once all references to
ThreadId
have been dropped. However, this simply means in practice that any unused contexts will cleaned up upon the next garbage collection and may not be actively freed when the program exits.
Note that this implementation of context sharing is mildly expensive for the garbage collector, hard to reason about without deep knowledge of the code you are instrumenting, and has limited guarantees of behavior across GHC versions due to internals usage.
Synopsis
- data ThreadStorageMap a
- newThreadStorageMap :: MonadIO m => m (ThreadStorageMap a)
- lookup :: MonadIO m => ThreadStorageMap a -> m (Maybe a)
- lookupOnThread :: MonadIO m => ThreadStorageMap a -> ThreadId -> m (Maybe a)
- update :: MonadIO m => ThreadStorageMap a -> (Maybe a -> (Maybe a, b)) -> m b
- updateOnThread :: MonadIO m => ThreadStorageMap a -> ThreadId -> (Maybe a -> (Maybe a, b)) -> m b
- attach :: MonadIO m => ThreadStorageMap a -> a -> m (Maybe a)
- attachOnThread :: MonadIO m => ThreadStorageMap a -> ThreadId -> a -> m (Maybe a)
- detach :: MonadIO m => ThreadStorageMap a -> m (Maybe a)
- detachFromThread :: MonadIO m => ThreadStorageMap a -> ThreadId -> m (Maybe a)
- adjust :: MonadIO m => ThreadStorageMap a -> (a -> a) -> m ()
- adjustOnThread :: MonadIO m => ThreadStorageMap a -> ThreadId -> (a -> a) -> m ()
- storedItems :: ThreadStorageMap a -> IO [(Int, a)]
- getThreadId :: ThreadId -> Word
Create a ThreadStorageMap
data ThreadStorageMap a Source #
A storage mechanism for values of a type. This structure retains items on per-(green)thread basis, which can be useful in rare cases.
newThreadStorageMap :: MonadIO m => m (ThreadStorageMap a) Source #
Create a new thread storage map. The map is striped by thread into 32 sections in order to reduce contention.
Retrieve values from a ThreadStorageMap
lookup :: MonadIO m => ThreadStorageMap a -> m (Maybe a) Source #
Retrieve a value if it exists for the current thread
lookupOnThread :: MonadIO m => ThreadStorageMap a -> ThreadId -> m (Maybe a) Source #
Retrieve a value if it exists for the specified thread
Update values in a ThreadStorageMap
updateOnThread :: MonadIO m => ThreadStorageMap a -> ThreadId -> (Maybe a -> (Maybe a, b)) -> m b Source #
The most general function in this library. Update a ThreadStorageMap
on a given thread,
with the ability to add or remove values and return some sort of result.
Associate values with a thread in a ThreadStorageMap
attach :: MonadIO m => ThreadStorageMap a -> a -> m (Maybe a) Source #
Associate the provided value with the current thread.
Returns the previous value if it was set.
attachOnThread :: MonadIO m => ThreadStorageMap a -> ThreadId -> a -> m (Maybe a) Source #
Associate the provided value with the specified thread. This replaces
any values already associated with the ThreadId
.
Remove values from a thread in a ThreadStorageMap
detach :: MonadIO m => ThreadStorageMap a -> m (Maybe a) Source #
Disassociate the associated value from the current thread, returning it if it exists.
detachFromThread :: MonadIO m => ThreadStorageMap a -> ThreadId -> m (Maybe a) Source #
Disassociate the associated value from the specified thread, returning it if it exists.
Update values for a thread in a ThreadStorageMap
adjust :: MonadIO m => ThreadStorageMap a -> (a -> a) -> m () Source #
Update the associated value for the current thread if it is attached.
adjustOnThread :: MonadIO m => ThreadStorageMap a -> ThreadId -> (a -> a) -> m () Source #
Update the associated value for the specified thread if it is attached.
Monitoring utilities
storedItems :: ThreadStorageMap a -> IO [(Int, a)] Source #
List thread ids with live entries in the ThreadStorageMap
.
This is useful for monitoring purposes to verify that there
are no memory leaks retaining threads and thus preventing
items from being freed from a ThreadStorageMap
Thread ID manipulation
getThreadId :: ThreadId -> Word Source #