#4078: hReady and h hWaitForInput block under Windows
-------------------------------+--------------------------------------------
    Reporter:  tbogdala        |       Owner:                                   
    
        Type:  bug             |      Status:  new                              
    
    Priority:  normal          |   Component:  libraries/base                   
    
     Version:  6.12.1          |    Keywords:  hReady hWaitForInput Windows 
blocking
          Os:  Windows         |    Testcase:                                   
    
Architecture:  x86_64 (amd64)  |     Failure:  Incorrect result at runtime      
    
-------------------------------+--------------------------------------------
 While using a Network.Socket converted to a Handle with socketToHandle,
 calling hReady or hWaitForInput on that handle will block.

 This happens within ghci or when compiled with -threaded and executed with
 "+RTS -N2 -RTS" options.

 I've attached a simple server.hs file that listens on a port. Once a
 client connects it loops until hReady returns true - then it will read
 from the port. Load it in gchi and execute something like:

 {{{
 servNumber "11333"
 }}}

 I've also attached a quick client.hs module to load in ghci to send data
 to the port. Load it in ghci and execute something like:

 {{{
 s1 <- openServer "localhost" "11333"
 write2Server "blash" s1
 }}}

 ----

 Here's the code.

 server.hs

 {{{
 import Network.Socket
 import Control.Concurrent
 import System.IO

 -- main = servNumber "11333"

 servNumber :: String -> IO ()
 servNumber port = withSocketsDo $ do
   addrInfos <- getAddrInfo
                     (Just (defaultHints {addrFlags = [AI_PASSIVE]}))
                     Nothing (Just port)
   let serveraddr = head addrInfos
   sock <- socket (addrFamily serveraddr) Stream defaultProtocol
   bindSocket sock (addrAddress serveraddr)
   listen sock 5
   procIncoming sock
  where
   procIncoming :: Socket -> IO ()
   procIncoming masterSock = do
     (conSock, _) <- accept masterSock
     forkIO $ doWork conSock
     procIncoming masterSock

   doWork :: Socket -> IO ()
   doWork conSock = do
     h <- socketToHandle conSock ReadWriteMode
     hSetBuffering h LineBuffering
     loop h

   loop :: Handle -> IO ()
   loop h = do
     putStrLn "Calling hReady."
     ready <- hReady h
     --ready <- hWaitForInput h 1
     if ready
         then hGetLine h >>= putStrLn >> loop h
         else loop h
 }}}

 client.hs

 {{{
 import Network.Socket
 import Control.Concurrent
 import System.IO


 openServer :: String -> String -> IO (Handle)
 openServer hostname port = withSocketsDo $ do
   addrinfos <- getAddrInfo Nothing (Just hostname) (Just port)
   let serveraddr = head addrinfos
   sock <- socket (addrFamily serveraddr) Stream defaultProtocol
   connect sock (addrAddress serveraddr)
   h <- socketToHandle sock ReadWriteMode
   hSetBuffering h LineBuffering
   return h

 write2Server :: String -> Handle -> IO ()
 write2Server msg h = do
   hPutStrLn h msg
   hFlush h

 closeServer :: Handle -> IO ()
 closeServer h = hClose h
 }}}

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/4078>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to