Created
September 28, 2017 13:22
-
-
Save nh2/6f571ce00667bc49d845ab4c8fdf9769 to your computer and use it in GitHub Desktop.
Shows how hWaitForInput eventually calls sycalls in GHC Haskell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Call chain of hWaitForInput: | |
-- | |
-- hWaitForInput | |
-- ready from the IODevice typeclass for type FD (from haDevice of a Handle__) | |
-- ready from base/GHC.IO.FD | |
-- fdReady foreign import from base/GHC.IO.FD | |
-- Exact locations and code: | |
-- http://hackage.haskell.org/package/base-4.10.0.0/docs/src/GHC.IO.Handle.Text.html#local-6989586621679305954 | |
hWaitForInput :: Handle -> Int -> IO Bool | |
hWaitForInput h msecs = do | |
wantReadableHandle_ "hWaitForInput" h $ \ handle_@Handle__{..} -> do | |
cbuf <- readIORef haCharBuffer | |
if not (isEmptyBuffer cbuf) then return True else do | |
if msecs < 0 | |
then do cbuf' <- readTextDevice handle_ cbuf | |
writeIORef haCharBuffer cbuf' | |
return True | |
else do | |
-- there might be bytes in the byte buffer waiting to be decoded | |
cbuf' <- decodeByteBuf handle_ cbuf | |
writeIORef haCharBuffer cbuf' | |
if not (isEmptyBuffer cbuf') then return True else do | |
r <- IODevice.ready haDevice False{-read-} msecs -------ready call HERE | |
if r then do -- Call hLookAhead' to throw an EOF | |
-- exception if appropriate | |
_ <- hLookAhead_ handle_ | |
return True | |
else return False | |
-- http://hackage.haskell.org/package/base-4.10.0.0/docs/GHC-IO-Device.html#t:IODevice | |
class IODevice a where | |
-- | @ready dev write msecs@ returns 'True' if the device has data | |
-- to read (if @write@ is 'False') or space to write new data (if | |
-- @write@ is 'True'). @msecs@ specifies how long to wait, in | |
-- milliseconds. | |
-- | |
ready :: a -> Bool -> Int -> IO Bool | |
-- https://github.com/ghc/ghc/blob/ghc-8.2.1-release/libraries/base/GHC/IO/FD.hs#L103 | |
instance GHC.IO.Device.IODevice FD where | |
ready = ready | |
-- https://github.com/ghc/ghc/blob/ghc-8.2.1-release/libraries/base/GHC/IO/FD.hs#L395 | |
ready :: FD -> Bool -> Int -> IO Bool | |
ready fd write msecs = do | |
r <- throwErrnoIfMinus1Retry "GHC.IO.FD.ready" $ | |
fdReady (fdFD fd) (fromIntegral $ fromEnum $ write) | |
(fromIntegral msecs) | |
#if defined(mingw32_HOST_OS) | |
(fromIntegral $ fromEnum $ fdIsSocket fd) | |
#else | |
0 | |
#endif | |
return (toEnum (fromIntegral r)) | |
-- https://github.com/ghc/ghc/blob/ghc-8.2.1-release/libraries/base/GHC/IO/FD.hs#L407 | |
foreign import ccall safe "fdReady" | |
fdReady :: CInt -> CInt -> CInt -> CInt -> IO CInt |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment