-
Notifications
You must be signed in to change notification settings - Fork 0
Exception handling by example
Yuras edited this page Nov 15, 2014
·
1 revision
Here I'll collect useful or simply interesting examples of exception handling in Haskell. It is not directly related to io-region
package.
Here is possible implementation of timeout
(from ghc sources):
newtype Timeout = Timeout Unique
instance Show Timeout where
timeout :: Int -> IO a -> IO a
timeout n f = do
pid <- myThreadId
ex <- fmap Timeout newUnique
handleJust (\e -> if e == ex then Just () else Nothing)
(\_ -> return Nothing)
(bracket (forkIOWithUnmask $ \unmask ->
unmask $ threadDelay n >> throwTo pid ex)
(uninterruptibleMask_ . killThread)
(\_ -> fmap Just f))
Note that killThread
is implemented via throwTo
, so we have mutual throwTo
.
throwTo
is interruptible and atomic, so only one throwTo
will succeed interrupting another one.
uninterruptibleMask_
here looks unnecessary in the first glance because killThread
can't block here (but can be descheduled.) But:
-
killThread
is interruptible even when it doesn't block, unlike most other actions - it can actually block here waiting for child thread to unmask async exceptions
But
uninterruptibleMask_
here is guaranteed to take small (well, bounded) amount of time, so it is safe.