thread-utils-context-0.3.0.4: Garbage-collected thread local storage
Safe HaskellNone
LanguageHaskell2010

Control.Concurrent.Thread.Storage

Description

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 attached to a ThreadId will remain alive at least as long as the ThreadId.
  • A value may be detached from a ThreadId via detach 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

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

update :: MonadIO m => ThreadStorageMap a -> (Maybe a -> (Maybe a, b)) -> m b Source #

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