[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [win-pv-devel] [PATCH 05/14] Add a short Sleep between CreateFile calls





On Thu, Jan 25, 2018 at 11:37 AM, Paul Durrant <Paul.Durrant@xxxxxxxxxx> wrote:
<snip>
> +    // add a small delay here, to prevent the second CreateFile returning with
> +    // all pipe instances busy - this gives the server end some time to spawn
> +    // the read pipe and return to ConnectNamedPipe
> +    Sleep(50);
> +
>      Context->Device.Write = CreateFile(PIPE_NAME,
>                                         GENERIC_WRITE,
>                                         FILE_SHARE_READ | FILE_SHARE_WRITE,

I'm not fan of arbitrary delays. Could you handle this by catching the error and retrying instead?

  Paul


First, to Owen: It would be very helpful to have some context on these patches.  I had to really root around to discover that these patches were for a repo called "xencons".

Second, to Paul:

You are correct - this Sleep(50) really should be replaced by WaitNamedPipe(50), and it should probably be done for *both* CreateFile calls, not just the one.

Background:
I believe it would be most helpful to start with the key differences between accepting a socket connection and accepting a Win32 named pipe connection.

To start accepting socket connections, you call listen() with a parameter (I usually use 5 or so).   This parameter, called "backlog", represents the maximum number of pending connection requests against that socket. If connections come in and there isn't an active accept() call running against the socket, it will go into the backlog, and the next accept() call will pull that connection off the backlog and create a new socket to operate on. If the backlog is full, the OS will immediately reject the connection request with a "connection refused" error code.

To accept a named pipe connection, you create a named pipe with CreateNamedPipe (which does exactly what the name implies) then call ConnectNamedPipe (which actually means "wait for a client to connect to the named pipe").
In socket terms, CreateNamedPipe is a combination of socket() and listen(), while ConnectNamedPipe is like accept(). The key difference is this: accept() creates a socket and leaves the listening socket ready for new connections, while ConnectNamedPipe actually converts the passed pipe from a listening pipe to a connected pipe.  Because of this, a named pipe instance is limited to a backlog of 1. In order to accept multiple clients simultaneously, a server needs to create multiple instances of each pipe.
Just like in sockets, attempting to connect when the backlog is full will result in 'named pipe busy' error.

To help deal with this problem, the WaitNamedPipe function waits, with a timeout, until an unconnected pipe instance is available (either a connected pipe is disconnected and put back into a listening state, or a new pipe instance is created.).
Note that this function does not *claim* an instance, it only waits until one exists.  So it's possible to have WaitNamedPipe to return success, then another thread jumps in and grabs it before you can, and CreateFile fails anyway.  This caveat is specifically called out in the WaitNamedPipe documentation.

--
-- Stevie-O
Real programmers use COPY CON PROGRAM.EXE

_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/win-pv-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.