[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