[PATCH 3 of 3] windows: convert readpipe() to nonblocking like 331cbf088c4c does for posix

Yuya Nishihara yuya at tcha.org
Tue Apr 7 07:56:38 CDT 2015


On Mon, 06 Apr 2015 22:49:02 -0400, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison <matt_harbison at yahoo.com>
> # Date 1428373243 14400
> #      Mon Apr 06 22:20:43 2015 -0400
> # Node ID 7a8e37db057fb3b1fb77ee08df83076e1a527af7
> # Parent  5ad3c1f7fa75a06307f430ee51c19d85e6c78d14
> windows: convert readpipe() to nonblocking like 331cbf088c4c does for posix
> 
> There are several places in the Windows SSH tests where the order of local
> output vs remote output differ from the other platforms.  This only fixes one of
> those cases (and interstingly, not the one added in order to test 331cbf088c4c),
> so there is more investigation needed.  However, without this patch, test-ssl.t
> also has this diff:
> 
>     --- c:/Users/Matt/Projects/hg/tests/test-ssh.t
>     +++ c:/Users/Matt/Projects/hg/tests/test-ssh.t.err
>     @@ -397,11 +397,11 @@
>        $ hg push --ssh "sh ../ssh.sh"
>        pushing to ssh://user@dummy/*/remote (glob)
>        searching for changes
>     -  remote: Permission denied
>     -  remote: abort: prechangegroup.hg-ssh hook failed
>     -  remote: Permission denied
>     -  remote: pushkey-abort: prepushkey.hg-ssh hook failed
>        updating 6c0482d977a3 to public failed!
>     +  remote: Permission denied
>     +  remote: abort: prechangegroup.hg-ssh hook failed
>     +  remote: Permission denied
>     +  remote: pushkey-abort: prepushkey.hg-ssh hook failed
>        [1]
> 
>        $ cd ..
> 
> Output with this change was stable over 700+ runs of test-ssl.t.  I initially
> tried a background thread to read the pipe[1], but this was simpler and the test
> results were exactly the same.
> 
> [1] http://eyalarubas.com/python-subproc-nonblock.html
> 
> diff --git a/mercurial/win32.py b/mercurial/win32.py
> --- a/mercurial/win32.py
> +++ b/mercurial/win32.py
> @@ -243,6 +243,8 @@
>      finally:
>          _kernel32.CloseHandle(fh)
>  
> +PIPE_NOWAIT = 1
> +
>  def getpipestate(pipe):
>      handle = msvcrt.get_osfhandle(pipe.fileno())
>      if handle == -1:
> diff --git a/mercurial/windows.py b/mercurial/windows.py
> --- a/mercurial/windows.py
> +++ b/mercurial/windows.py
> @@ -362,14 +362,19 @@
>  def readpipe(pipe):
>      """Read all available data from a pipe."""
>      chunks = []
> -    while True:
> -        size = os.fstat(pipe.fileno()).st_size
> -        if not size:
> -            break
> +    oldstate = win32.getpipestate(pipe)
> +    win32.setpipestate(pipe, win32.PIPE_NOWAIT)

The doc says "Note that nonblocking mode [...] should not be used to achieve
asynchronous input and output (I/O) with named pipes."

https://msdn.microsoft.com/en-us/library/windows/desktop/aa365787%28v=vs.85%29.aspx

IIRC, PeekNamedPipe(h, NULL, 0, NULL, &availsize, NULL) can be used to get
the available size without blocking.

https://msdn.microsoft.com/en-us/library/windows/desktop/aa365779(v=vs.85).aspx

"The function always returns immediately in a single-threaded application, even
if there is no data in the pipe. The wait mode of a named pipe handle (blocking
or nonblocking) has no effect on the function."

Regards,


More information about the Mercurial-devel mailing list