Fix hWaitForInput
authorSimon Marlow <marlowsd@gmail.com>
Thu, 27 Aug 2009 15:21:16 +0000 (15:21 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Thu, 27 Aug 2009 15:21:16 +0000 (15:21 +0000)
It was erroneously waiting when there were bytes to decode waiting in
the byte buffer.

GHC/IO/Handle/Internals.hs
GHC/IO/Handle/Text.hs

index 3214bfd..a948b65 100644 (file)
@@ -793,13 +793,19 @@ readTextDeviceNonBlocking h_@Handle__{..} cbuf = do
   bbuf1 <- if not (isEmptyBuffer bbuf0)
               then return bbuf0
               else do
-                   (r,bbuf1) <- Buffered.fillReadBuffer haDevice bbuf0
-                   if r == 0 then ioe_EOF else do  -- raise EOF
+                   (r,bbuf1) <- Buffered.fillReadBuffer0 haDevice bbuf0
+                   if isNothing r then ioe_EOF else do  -- raise EOF
                    return bbuf1
 
-  (bbuf2,cbuf') <- case haDecoder of
-                     Nothing      -> latin1_decode bbuf1 cbuf
-                     Just decoder -> (encode decoder) bbuf1 cbuf
+  (bbuf2,cbuf') <-
+      case haDecoder of
+          Nothing      -> do
+               writeIORef haLastDecode (error "codec_state", bbuf1)
+               latin1_decode bbuf1 cbuf
+          Just decoder -> do
+               state <- getState decoder
+               writeIORef haLastDecode (state, bbuf1)
+               (encode decoder) bbuf1 cbuf
 
   writeIORef haByteBuffer bbuf2
   return cbuf'
index 168a5a5..ed3a106 100644 (file)
@@ -78,22 +78,32 @@ import GHC.List
 hWaitForInput :: Handle -> Int -> IO Bool
 hWaitForInput h msecs = do
   wantReadableHandle_ "hWaitForInput" h $ \ handle_@Handle__{..} -> do
-  buf <- readIORef haCharBuffer
+  cbuf <- readIORef haCharBuffer
 
-  if not (isEmptyBuffer buf)
-        then return True
-        else do
+  if not (isEmptyBuffer cbuf) then return True else do
 
   if msecs < 0 
-        then do buf' <- readTextDevice handle_ buf
-                writeIORef haCharBuffer buf'
+        then do cbuf' <- readTextDevice handle_ cbuf
+                writeIORef haCharBuffer cbuf'
                 return True
-        else do r <- IODevice.ready haDevice False{-read-} msecs
+        else do
+               -- there might be bytes in the byte buffer waiting to be decoded
+               cbuf' <- readTextDeviceNonBlocking handle_ cbuf
+               writeIORef haCharBuffer cbuf'
+
+               if not (isEmptyBuffer cbuf') then return True else do
+
+                r <- IODevice.ready haDevice False{-read-} msecs
                 if r then do -- Call hLookAhead' to throw an EOF
                              -- exception if appropriate
                              _ <- hLookAhead_ handle_
                              return True
                      else return False
+                -- XXX we should only return when there are full characters
+                -- not when there are only bytes.  That would mean looping
+                -- and re-running IODevice.ready if we don't have any full
+                -- characters; but we don't know how long we've waited
+                -- so far.
 
 -- ---------------------------------------------------------------------------
 -- hGetChar