-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Garbage-collected thread local storage
--
-- Please see the README on GitHub at
-- https://github.com/iand675/thread-utils-context#readme
@package thread-utils-context
@version 0.2.0.0
-- | 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: This library assumes that ThreadIds 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.
module Control.Concurrent.Thread.Storage
-- | A storage mechanism for values of a type. This structure retains items
-- on per-(green)thread basis, which can be useful in rare cases.
data ThreadStorageMap a
-- | Create a new thread storage map. The map is striped by thread into 32
-- sections in order to reduce contention.
newThreadStorageMap :: MonadIO m => m (ThreadStorageMap a)
-- | Retrieve a value if it exists for the current thread
lookup :: MonadIO m => ThreadStorageMap a -> m (Maybe a)
-- | Retrieve a value if it exists for the specified thread
lookupOnThread :: MonadIO m => ThreadStorageMap a -> ThreadId -> m (Maybe a)
-- | Associate the provided value with the current thread
attach :: MonadIO m => ThreadStorageMap a -> a -> m (Maybe a)
-- | Associate the provided value with the specified thread
attachOnThread :: MonadIO m => ThreadStorageMap a -> ThreadId -> a -> m (Maybe a)
-- | Disassociate the associated value from the current thread, returning
-- it if it exists.
detach :: MonadIO m => ThreadStorageMap a -> m (Maybe a)
-- | Disassociate the associated value from the specified thread, returning
-- it if it exists.
detachFromThread :: MonadIO m => ThreadStorageMap a -> ThreadId -> m (Maybe a)
-- | Update the associated value for the current thread if it is attached.
adjust :: MonadIO m => ThreadStorageMap a -> (a -> a) -> m ()
-- | Update the associated value for the specified thread if it is
-- attached.
adjustOnThread :: MonadIO m => ThreadStorageMap a -> ThreadId -> (a -> a) -> m ()
-- | 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
storedItems :: ThreadStorageMap a -> IO [(Int, a)]