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: This library assumes that ThreadId
s aren't reused before a finalizer runs to
clean up the ThreadStorageMap
, so quick thread churn of this nature.
Also note: This implementation of context sharing is
mildly expensive (~40ns to attach
a value) relative to using pure code / idiomatic things
like MonadReader, hard to reason about without deep knowledge of threading in the code you are
using, 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)
- 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)]
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
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
attachOnThread :: MonadIO m => ThreadStorageMap a -> ThreadId -> a -> m (Maybe a) Source #
Associate the provided value with the specified thread
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