MVar interface [was: Re: ForeignPtr-related signatures]

Dean Herington heringto at cs.unc.edu
Mon Nov 18 12:35:55 EST 2002


I wrote:

> One might reasonably worry about the proliferation of MVar manipulation
> functions.  I think it's useful to realize that there are semantically only
> four primitives in the proposed extended interface: `newEmptyMVar`,
> `atomicModifyMVar`, `atomicTryModifyMVar`, and `addMVarFinalizer`.  All the
> other functions can be built simply out of these primitives.  In fact, I
> would recommend we include in the documentation for all the nonprimitive
> functions their definitions in terms of the primitives.

Oops, I misspoke.  There are eight primitives in my proposed set.  Here's the
full story, including the definitions I suggest for the documentation.

 -- Dean


-- primitives

newEmptyMVar             :: IO (MVar v)

takeMVar                 :: MVar v -> IO v
putMVar                  :: MVar v -> v -> IO ()
atomicModifyMVar         :: MVar v -> (v -> (v,r)) -> IO r

tryTakeMVar              :: MVar v -> IO (Maybe v)
tryPutMVar               :: MVar v -> v -> IO Bool
atomicTryModifyMVar      :: MVar v -> (v -> (v,r)) -> IO (Maybe r)

addMVarFinalizer         :: MVar v -> IO () -> IO ()

-- nonprimitives

newMVar                  :: v -> IO (MVar v)
newMVar v                =  do m <- newEmptyMVar
                               putMVar m v
                               return m

atomicModifyMVar_        :: MVar v -> (v -> v) -> IO ()
atomicModifyMVar_ m f    =  atomicModifyMVar m (\v -> (f v, ()))

readMVar                 :: MVar v -> IO v
readMVar m               =  atomicModifyMVar m (\v -> (v, v))

swapMVar                 :: MVar v -> v -> IO v
swapMVar m v'            =  atomicModifyMVar m (\v -> (v', v))

atomicTryModifyMVar_     :: MVar v -> (v -> v) -> IO Bool
atomicTryModifyMVar_ m f =  do mr <- atomicTryModifyMVar m (\v -> (f v, ()))
                               return (isJust mr)

tryReadMVar              :: MVar v -> IO (Maybe v)
tryReadMVar m            =  atomicTryModifyMVar m (\v -> (v, v))

trySwapMVar              :: MVar v -> v -> IO (Maybe v)
trySwapMVar m v'         =  atomicTryModifyMVar m (\v -> (v', v))

isEmptyMVar              :: MVar v -> IO Bool
isEmptyMVar m            =  do mr <- atomicTryModifyMVar m (\v -> (v, ()))
                               return (isNothing mr)

modifyMVar               :: MVar v -> (v -> IO (v,r)) -> IO r
modifyMVar m io          =  block $ do
                             v      <- takeMVar m
                             (v',r) <- Exception.catch (unblock (io v))
                                         (\e -> do putMVar m v; throw e)
                             putMVar m v'
                             return r

modifyMVar_              :: MVar v -> (v -> IO v) -> IO ()
modifyMVar_ m io         =  block $ do
                              v  <- takeMVar m
                              v' <- Exception.catch (unblock (io v))
                                      (\e -> do putMVar m v; throw e)
                              putMVar m v'

withMVar                 :: MVar v -> (v -> IO r) -> IO r
withMVar m io            =  block $ do
                              v <- takeMVar m
                              r <- Exception.catch (unblock (io v))
                                     (\e -> do putMVar m v; throw e)
                              putMVar m v
                              return r





More information about the FFI mailing list