[Haskell-cafe] Implementing tryReadMVar
Einar Karttunen
ekarttun at cs.helsinki.fi
Wed Sep 1 10:44:12 EDT 2004
On 01.09 09:27, Jan-Willem Maessen - Sun Labs East wrote:
> Einar Karttunen wrote:
> >Hello
> >
> >Is it possible to implement an operation like
> >tryReadMVar :: MVar a -> IO (Maybe a)
> >in a good fashion? The semantics should be
> >"Read the value of the MVar without taking
> >it if it is filled, otherwise return Nothing".
> >
> >There are several easy and flawed implementations:
> >...
> >tryReadMVar mv = do mc <- tryTakeMVar mv
> > case mc of
> > Nothing -> return mc
> > Just v -> putMVar mv v >> return mc
> >
> >Now this can block on the putMVar if there was a thread switch
> >and someone filled the MVar behind our back.
>
> This sets off alarm bells in my head. What are you actually trying to
> do, and why is correct for mutiple threads to race to "putMVar"?
There are several cases in which multiple threads racing putMVar is
correct. Consider e.g. a server thread encapsulating state, which
needs to rate limit its clients. The server is put behind a MVar
to which all the clients putMVar and thus block until the server
is ready e.g.
plumbIn :: MVar SCoreT -> HId -> Handle -> IO ()
plumbIn mv hid h = hGetContents h >>= loop
where loop s = let (m,r) = readInput s in putMVar mv (Msg m hid) >> loop r
The server thread uses tryTakeMVar for its job.
Now add a debug function:
debug :: MVar SCoreT -> IO ()
debug mv = tryReadMVar mv >>= maybe (putStrLn "Nothing") print
And suddenly we have a created a subtle bug in the code with
flawed tryReadMVar implementation.
- Einar Karttunen
More information about the Haskell-Cafe
mailing list