{-# language MagicHash #-} {-# language UnboxedTuples #-} {-# language LambdaCase #-} -- | -- Copyright : (c) 2019-2021 Edward Kmett -- License : BSD-2-Clause OR Apache-2.0 -- Maintainer: Edward Kmett -- Stability : experimental -- Portability: non-portable -- module System.Mem.Weak.IORef ( mkWeakIORef' , mkWeakIORefPtr , mkWeakIORefPair ) where import GHC.Base import GHC.Weak import GHC.IORef import GHC.STRef -- | Make an arbitrary 'Weak' reference from a 'Data.IORef.IORef'. -- -- Provides a more general API than the crippled one offered by 'Data.IORef.mkWeakIORef' -- to match the power of 'mkWeak'. mkWeakIORef' :: IORef k -> v -> Maybe (IO ()) -> IO (Weak v) mkWeakIORef' (IORef (STRef k#)) v = \case Nothing -> IO $ \s -> case mkWeakNoFinalizer# k# v s of (# s1, w #) -> (#s1, Weak w #) Just (IO finalizer) -> IO $ \s -> case mkWeak# k# v finalizer s of (# s1, w #) -> (#s1, Weak w #) {-# inlinable mkWeakIORef' #-} -- | Functions like 'System.Mem.Weak.mkWeakPtr' but for 'Data.IORef.IORef's. -- -- Make an arbitrary 'Weak' reference from an 'Data.IORef.IORef' and an optional finalizer. -- -- A specialised version of 'mkWeakIORef'' where the key and value are the same. mkWeakIORefPtr :: IORef k -> Maybe (IO ()) -> IO (Weak (IORef k)) mkWeakIORefPtr k = mkWeakIORef' k k {-# inlinable mkWeakIORefPtr #-} -- | -- -- A specialised version of 'mkWeakIORef'' where the value is actually a pair of the -- key and value passed to 'mkWeakIORefPair': -- -- @ -- 'mkWeakIORefPair' key val finalizer ≡ 'mkWeakIORef'' key (key,val) finalizer -- @ -- -- The advantage of this is that the key can be retrieved by 'deRefWeak' in addition to the value. mkWeakIORefPair :: IORef k -> v -> Maybe (IO ()) -> IO (Weak (IORef k, v)) mkWeakIORefPair k v = mkWeakIORef' k (k,v) {-# inlinable mkWeakIORefPair #-}