
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