module Util.ReferenceCount(
RefCount,
newRefCount,
newLinkedRefCount,
addRef,
remRef,
) where
import Control.Concurrent.MVar
newtype RefCount = RefCount (MVar Int)
newRefCount :: IO RefCount
newRefCount :: IO RefCount
newRefCount =
do
MVar Int
mVar <- Int -> IO (MVar Int)
forall a. a -> IO (MVar a)
newMVar Int
0
RefCount -> IO RefCount
forall (m :: * -> *) a. Monad m => a -> m a
return (MVar Int -> RefCount
RefCount MVar Int
mVar)
newLinkedRefCount :: IO RefCount
newLinkedRefCount :: IO RefCount
newLinkedRefCount =
do
MVar Int
mVar <- Int -> IO (MVar Int)
forall a. a -> IO (MVar a)
newMVar Int
1
RefCount -> IO RefCount
forall (m :: * -> *) a. Monad m => a -> m a
return (MVar Int -> RefCount
RefCount MVar Int
mVar)
addRef :: RefCount -> IO ()
addRef :: RefCount -> IO ()
addRef (RefCount MVar Int
mVar) = MVar Int -> (Int -> IO Int) -> IO ()
forall a. MVar a -> (a -> IO a) -> IO ()
modifyMVar_ MVar Int
mVar (Int -> IO Int
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> IO Int) -> (Int -> Int) -> Int -> IO Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1))
remRef :: RefCount -> IO Bool
remRef :: RefCount -> IO Bool
remRef (RefCount MVar Int
mVar) = MVar Int -> (Int -> IO (Int, Bool)) -> IO Bool
forall a b. MVar a -> (a -> IO (a, b)) -> IO b
modifyMVar MVar Int
mVar (\ Int
count0 ->
let
count1 :: Int
count1 = Int
count0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
in
(Int, Bool) -> IO (Int, Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
count1,Int
count1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0)
)