The definition of threadWait is: threadWait :: Event <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Internal.html#Event> -> Fd <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/System.Posix.Types.html#Fd> -> IO ()threadWait <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Thread.html#threadWait> evt <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Thread.html#local-6989586621679365266> fd <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Thread.html#local-6989586621679365267> = mask_ <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.IO.html#mask_> $ <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Base.html#%24> do m <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Thread.html#local-6989586621679365268> <- newEmptyMVar <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.MVar.html#newEmptyMVar> mgr <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Thread.html#local-6989586621679365269> <- getSystemEventManager_ <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Thread.html#getSystemEventManager_> reg <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Thread.html#local-6989586621679365271> <- registerFd <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Manager.html#registerFd> mgr <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Thread.html#local-6989586621679365269> (\_ e <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Thread.html#local-6989586621679365270> -> putMVar <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.MVar.html#putMVar> m <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Thread.html#local-6989586621679365268> e <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Thread.html#local-6989586621679365270>) fd <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Thread.html#local-6989586621679365267> evt <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Thread.html#local-6989586621679365266> M.OneShot <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Internal.html#OneShot> evt' <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Thread.html#local-6989586621679365272> <- takeMVar <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.MVar.html#takeMVar> m <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Thread.html#local-6989586621679365268> `onException <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.IO.html#onException>` unregisterFd_ <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Manager.html#unregisterFd_> mgr <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Thread.html#local-6989586621679365269> reg <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Thread.html#local-6989586621679365271> if evt' <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Thread.html#local-6989586621679365272> `eventIs <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Internal.html#eventIs>` evtClose <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Event.Internal.html#evtClose> then ioError <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.IO.Exception.html#ioError> $ <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Base.html#%24> errnoToIOError <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/Foreign.C.Error.html#errnoToIOError> "threadWait" eBADF <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/Foreign.C.Error.html#eBADF> Nothing <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Maybe.html#Nothing> Nothing <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Maybe.html#Nothing> else return <http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Base.html#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