[GHC] #6057: hGetBufNonBlocking blocks the underlying handle on Windows

GHC cvs-ghc at haskell.org
Sun Apr 29 12:30:27 CEST 2012


#6057: hGetBufNonBlocking blocks the underlying handle on Windows
-----------------------------------------+----------------------------------
 Reporter:  cetinsert                    |          Owner:                  
     Type:  bug                          |         Status:  new             
 Priority:  normal                       |      Component:  libraries/base  
  Version:  7.0.4                        |       Keywords:                  
       Os:  Windows                      |   Architecture:  Unknown/Multiple
  Failure:  Incorrect result at runtime  |       Testcase:                  
Blockedby:                               |       Blocking:                  
  Related:                               |  
-----------------------------------------+----------------------------------
 In a cross-platform transport-layer proxy software I am developing, I have
 this piece of code:


 {{{
   a >- b $ j       -- forks
   b >- a $ j       -- forks
 }}}

 where a and b are handles; j is an exception handler and (>-) is a self-
 forking infinite loop IO that splices data between two handles, defined
 previously in terms of hGetBufSome and and hPutBuf on Windows.

 I just noticed that:


 {{{
   b >- a $ j       -- forks
   a >- b $ j       -- forks
 }}}

 behaves differently from:


 {{{
   a >- b $ j       -- forks
   b >- a $ j       -- forks
 }}}

 When proxying connections to an SSH server the first one does not show the
 greeting from the SSH server before receiving user input, the second does
 show the greeting.

 As the two lines immediately fork to their own Haskell threads the
 blocking must come from the underlying handles.

 When I attempted to use hGetBufNonBlocking to avoid the problem I noticed
 that the docs read: "NOTE: on Windows, this function does not work
 correctly; it behaves identically to hGetBuf.".

 The reason I chose to use handles in the first place was the "Improving
 I/O Performance over sockets" section in the network package:
 http://hackage.haskell.org/packages/archive/network/2.3.0.13/doc/html/Network.html.

 At this point I am stuck as neither the network package exports functions
 that work on pointers to pre-allocated memory buffers nor the h---- famiy
 of functions from System.IO behave as their names suggest.

 Defining (>-) in terms of recv and sendAll from Network.Socket.ByteString
 does show the problem and both variants behave exactly the same at run
 time and this is the only correct behaviour as I have no way of knowing or
 special-casing which application layer protocols expect initiation from
 which end (client input first or server greeting first).

 I am reporting this issue to both here and to the maintainers of the
 network package on GitHub .

 This bug is reported for 7.0.4 but I highly suspect the behavior may still
 be the same with newer GHC versions.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/6057>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler



More information about the Glasgow-haskell-bugs mailing list