Timeout.hs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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. isEOF (FixedTimeout _ u) = isEOF u
  40. {- |
  41. Variable timeout, set at runtime.
  42. > MVarTimeout tm u
  43. Will wrap u, reading the timeout from (and locking) tm
  44. during every read and write operation.
  45. -}
  46. data MVarTimeout = forall u. UniformIO u => MVarTimeout (MVar Int) u
  47. instance UniformIO MVarTimeout where
  48. uRead (MVarTimeout t' u) i = withMVar t' $ \t -> do
  49. r' <- timeout t $ uRead u i
  50. case r' of
  51. Just r -> return r
  52. Nothing -> doTimeout
  53. uPut (MVarTimeout t' u) tx = withMVar t' $ \t -> do
  54. r' <- timeout t $ uPut u tx
  55. case r' of
  56. Just _ -> return ()
  57. Nothing -> doTimeout
  58. uClose (MVarTimeout _ u) = uClose u
  59. startTls s (MVarTimeout t' u) = withMVar t' $ \t -> do
  60. r' <- timeout t $ startTls s u
  61. case r' of
  62. Just r -> return $ MVarTimeout t' r
  63. Nothing -> doTimeout
  64. isSecure (MVarTimeout _ u) = isSecure u
  65. isEOF (MVarTimeout _ u) = isEOF u
  66. doTimeout :: IO a
  67. doTimeout = ioError $ userError "Timeout"