diff options
author | Alina Banerjee <alina@glitchgirl.us> | 2021-07-19 03:59:12 +0000 |
---|---|---|
committer | Alina Banerjee <alina@glitchgirl.us> | 2021-07-19 22:38:29 +0000 |
commit | c708b969bafb403d482565601f8d0ed963e54a3c (patch) | |
tree | 81ea1c9f198a34af8807b2765311d54293b4648b /utils/benchmarks/events/EventFile.hs | |
parent | de9fedc380d22ff6db3e4c7540af07b99d26fbd9 (diff) | |
download | haskell-wip/fix-8045.tar.gz |
Move event benchmarks to utils/benchmarks/events/wip/fix-8045
Diffstat (limited to 'utils/benchmarks/events/EventFile.hs')
-rw-r--r-- | utils/benchmarks/events/EventFile.hs | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/utils/benchmarks/events/EventFile.hs b/utils/benchmarks/events/EventFile.hs new file mode 100644 index 0000000000..1edad86a89 --- /dev/null +++ b/utils/benchmarks/events/EventFile.hs @@ -0,0 +1,49 @@ +{-# LANGUAGE CPP #-} + +-- | File functions using System.Event instead of GHC's I/O manager. +module EventFile + ( + read + ) where + +import Data.ByteString (ByteString) +import Data.ByteString.Internal (createAndTrim) +import Data.Word (Word8) +import Foreign.Ptr (Ptr, castPtr) +import Foreign.C.Error (eINTR, getErrno, throwErrno) +#if __GLASGOW_HASKELL__ < 612 +import GHC.IOBase (IOErrorType(..)) +#else +import GHC.IO.Exception (IOErrorType(..)) +#endif +#if defined(USE_GHC_IO_MANAGER) +import GHC.Conc (threadWaitRead) +#else +import GHC.Event (threadWaitRead) +#endif +import System.IO.Error (ioeSetErrorString, mkIOError) +import System.Posix.Internals (c_read) +import System.Posix.Types (Fd) +import Prelude hiding (read) +import EventUtil + +read :: Fd -> Int -> IO ByteString +read fd nbytes + | nbytes <= 0 = ioError (mkInvalidReadArgError "read") + | otherwise = createAndTrim nbytes $ readInner fd nbytes + +readInner :: Fd -> Int -> Ptr Word8 -> IO Int +readInner fd nbytes ptr = do + len <- throwErrnoIfMinus1Retry_repeatOnBlock "read" + (threadWaitRead (fromIntegral fd)) $ + c_read (fromIntegral fd) (castPtr ptr) (fromIntegral nbytes) + case fromIntegral len of + (-1) -> do errno <- getErrno + if errno == eINTR + then readInner fd nbytes ptr + else throwErrno "read" + n -> return n + +mkInvalidReadArgError :: String -> IOError +mkInvalidReadArgError loc = ioeSetErrorString + (mkIOError InvalidArgument loc Nothing Nothing) "non-positive length" |