module Data.CBMVar
( CBMVar
, newCBMVar
, readCBMVar
, writeCBMVar
, modifyCBMVar
, installCallbackCBMVar
)
where
import Control.Concurrent.MVar
data CBMVar a = CBMVar (MVar (a, [IO ()]))
newCBMVar :: a -> IO (CBMVar a)
newCBMVar v = fmap CBMVar $ newMVar (v,[])
readCBMVar :: CBMVar a -> IO a
readCBMVar (CBMVar ref) = fmap fst $ readMVar ref
writeCBMVar :: CBMVar a -> a -> IO ()
writeCBMVar (CBMVar ref) v = do
modifyMVar_ ref (\(_,cb) -> return (v,cb))
runCallbacks ref
runCallbacks :: MVar (a, [IO ()]) -> IO ()
runCallbacks ref = (sequence_.snd) =<< readMVar ref
modifyCBMVar :: CBMVar a -> (a -> IO a) -> IO ()
modifyCBMVar (CBMVar ref) f = do
modifyMVar_ ref (\(v,cb) -> f v >>= \v' -> return (v',cb))
runCallbacks ref
installCallbackCBMVar :: CBMVar a -> IO () -> IO ()
installCallbackCBMVar (CBMVar ref) p =
modifyMVar_ ref (\(v,cb) -> return (v,cb ++ [p]))