packages feed

cinvoke-0.1: Data/RefCount.hs

{- | Reference counting
    Data with a finalizer that will be called when the counter reached zero.
    Thread-safe. -}
module Data.RefCount (
    RefCount,
    newRefCount,
    incRefCount,
    decRefCount,
) where

import Control.Monad
import Data.IORef

data RefCount = RefCount !(IO ()) !(IORef Int)

newRefCount cleanup = RefCount cleanup `liftM` newIORef 1

incRefCount (RefCount _ ref) = atomicModifyIORef ref $ \x -> (succ x, ())

decRefCount (RefCount cleanup ref) = do
    refCnt <- atomicModifyIORef ref $ \x -> let x' = pred x in (x', x')
    when (refCnt == 0)
        cleanup