Michael Walker explained quite well why that's reasonable. What seems much *less* reasonable is that the function masks exceptions right from the start and all the way to the end. I don't see any reason to mask until after calling getSystemEventManager_, or to remain masked after taking the MVar.

On Thu, Jan 17, 2019 at 5:17 PM Andrew Martin <andrew.thaddeus@gmail.com> wrote:
The definition of threadWait is:
threadWait :: Event -> Fd -> IO ()
threadWait evt fd = mask_ $ do
  m <- newEmptyMVar
  mgr <- getSystemEventManager_
  reg <- registerFd mgr (\_ e -> putMVar m e) fd evt M.OneShot
  evt' <- takeMVar m `onException` unregisterFd_ mgr reg
  if evt' `eventIs` evtClose
    then ioError $ errnoToIOError "threadWait" eBADF Nothing Nothing
    else return ()
Although the entire function has asynchronous exceptions masked, the call to takeMVar uses onException to deal with the possibility of an exception. According to the docs in Control.Concurrent, takeMVar can throw exceptions. But my understand (which may be wrong) is that the only exception this could throw would be something like BlockedIndefinitelyOnMVar, which I don't believe can happen here.

--
-Andrew Thaddeus Martin
_______________________________________________
Libraries mailing list
Libraries@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries