hsgnutls-0.2.3.2: Network/GnuTLS/RefCount.hs
module Network.GnuTLS.RefCount
(RefCount, newRefCount, allocRef, freeRef, addRefFinalizer)
where
import Data.IORef
-- | A simple reference count with a list of finalizers.
newtype RefCount = RC (IORef (Int, [IO ()]))
-- | Create a new reference count with one reference and
-- the suplied action as the initial finalizer.
newRefCount :: IO () -> IO RefCount
newRefCount act = return . RC =<< newIORef (1, [act])
-- | Allocate an additional reference to the RefCount.
allocRef :: RefCount -> IO ()
allocRef (RC ref) = atomicModifyIORef ref $ \(iv,cs) -> ((iv+1,cs),())
-- | Free a reference to the RefCount. If the number
-- of references goes down to zero all the associated
-- finalizers are fired. The RefCount is left in
-- unusable state when all the references have been
-- deleted.
freeRef :: RefCount -> IO ()
freeRef (RC ref) = atomicModifyIORef ref handler >>= sequence_
where handler (1,cs) = (error "Double free of RefCount",cs)
handler (k,cs) = ((k-1,cs), [])
-- | Associate an additional finalizer with the RefCount.
addRefFinalizer :: RefCount -> IO () -> IO ()
addRefFinalizer (RC ref) c = atomicModifyIORef ref $ \(iv,cs) -> ((iv,c:cs),())