Timeout.hs 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. {-# LANGUAGE ExistentialQuantification #-}
  2. {- |
  3. Wraps a target placing reading and writting operations
  4. unders a timeout. Raises IOError if a timeout occurs.
  5. -}
  6. module System.IO.Uniform.Timeout (
  7. FixedTimeout(..),
  8. MVarTimeout(..)
  9. ) where
  10. import System.IO.Uniform
  11. import System.Timeout
  12. --import System.IO.Error
  13. import Control.Concurrent.MVar
  14. {- |
  15. Fixed timeout, set at define time.
  16. > FixTimeout tm u
  17. Will wrap u, applying a timeout of
  18. tm nanoseconds on its IO operations.
  19. -}
  20. data FixedTimeout = forall u. UniformIO u => FixedTimeout Int u
  21. instance UniformIO FixedTimeout where
  22. uRead (FixedTimeout t u) i = do
  23. r' <- timeout t $ uRead u i
  24. case r' of
  25. Just r -> return r
  26. Nothing -> doTimeout
  27. uPut (FixedTimeout t u) tx = do
  28. r' <- timeout t $ uPut u tx
  29. case r' of
  30. Just _ -> return ()
  31. Nothing -> doTimeout
  32. uClose (FixedTimeout _ u) = uClose u
  33. startTls s (FixedTimeout t u) = do
  34. r' <- timeout t $ startTls s u
  35. case r' of
  36. Just r -> return $ FixedTimeout t r
  37. Nothing -> doTimeout
  38. isSecure (FixedTimeout _ u) = isSecure u
  39. {- |
  40. Variable timeout, set at runtime.
  41. > MVarTimeout tm u
  42. Will wrap u, reading the timeout from (and locking) tm
  43. during every read and write operation.
  44. -}
  45. data MVarTimeout = forall u. UniformIO u => MVarTimeout (MVar Int) u
  46. instance UniformIO MVarTimeout where
  47. uRead (MVarTimeout t' u) i = withMVar t' $ \t -> do
  48. r' <- timeout t $ uRead u i
  49. case r' of
  50. Just r -> return r
  51. Nothing -> doTimeout
  52. uPut (MVarTimeout t' u) tx = withMVar t' $ \t -> do
  53. r' <- timeout t $ uPut u tx
  54. case r' of
  55. Just _ -> return ()
  56. Nothing -> doTimeout
  57. uClose (MVarTimeout _ u) = uClose u
  58. startTls s (MVarTimeout t' u) = withMVar t' $ \t -> do
  59. r' <- timeout t $ startTls s u
  60. case r' of
  61. Just r -> return $ MVarTimeout t' r
  62. Nothing -> doTimeout
  63. isSecure (MVarTimeout _ u) = isSecure u
  64. doTimeout :: IO a
  65. doTimeout = ioError $ userError "Timeout"