WaitForConnectionAsync() public method

public WaitForConnectionAsync ( ) : System.Threading.Tasks.Task
return System.Threading.Tasks.Task
Ejemplo n.º 1
0
        public async Task NamedPipeWriteViaAsyncFileStream(bool asyncWrites)
        {
            string name = Guid.NewGuid().ToString("N");
            using (var server = new NamedPipeServerStream(name, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
            {
                Task serverTask = Task.Run(async () =>
                {
                    await server.WaitForConnectionAsync();
                    for (int i = 0; i < 6; i++)
                        Assert.Equal(i, server.ReadByte());
                });

                WaitNamedPipeW(@"\\.\pipe\" + name, -1);
                using (SafeFileHandle clientHandle = CreateFileW(@"\\.\pipe\" + name, GENERIC_WRITE, FileShare.None, IntPtr.Zero, FileMode.Open, (int)PipeOptions.Asynchronous, IntPtr.Zero))
                using (var client = new FileStream(clientHandle, FileAccess.Write, bufferSize: 3, isAsync: true))
                {
                    var data = new[] { new byte[] { 0, 1 }, new byte[] { 2, 3 }, new byte[] { 4, 5 } };
                    foreach (byte[] arr in data)
                    {
                        if (asyncWrites)
                            await client.WriteAsync(arr, 0, arr.Length);
                        else
                            client.Write(arr, 0, arr.Length);
                    }
                }

                await serverTask;
            }
        }
Ejemplo n.º 2
0
        private async Task PrivateRunAsync(CancellationToken cancellationToken)
        {
            using (var pipe = new NamedPipeServerStream(ServerInfo.Name, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    await pipe.WaitForConnectionAsync(cancellationToken);

                    using (var reader = new NonClosingStreamReader(pipe))
                    using (var writer = new NonClosingStreamWriter(pipe) { AutoFlush = true })
                    {
                        var input = await reader.ReadCommandAsync();

                        _log.Information("Retrieved input {Input}", input);

                        switch (input)
                        {
                            case NamedPipeCommand.FindRepo:
                                await writer.WriteAsync(NamedPipeCommand.Ready);
                                await FindRepo(writer, await reader.ReadLineAsync(), cancellationToken);
                                break;
                            case NamedPipeCommand.GetAllRepos:
                                await writer.WriteAsync(NamedPipeCommand.Ready);
                                await GetAllRepos(writer, cancellationToken);
                                break;
                            case NamedPipeCommand.RemoveRepo:
                                await writer.WriteAsync(NamedPipeCommand.Ready);
                                await RemoveRepo(writer, reader, cancellationToken);
                                break;
                            case NamedPipeCommand.ClearCache:
                                await writer.WriteAsync(NamedPipeCommand.Ready);
                                await ProcessClearCacheAsync(writer, cancellationToken);
                                break;
                            case NamedPipeCommand.ExpandGitCommand:
                                await writer.WriteAsync(NamedPipeCommand.Ready);
                                await ProcessExpandGitCommandAsync(writer, reader, cancellationToken);
                                break;
                            default:
                                await writer.WriteAsync(NamedPipeCommand.BadCommand);
                                break;
                        }
                    }

                    // This must be after the reader and writer are closed
                    // Otherwise, an InvalidOperationException is thrown
                    pipe.WaitForPipeDrain();
                    pipe.Disconnect();
                }
            }
        }
Ejemplo n.º 3
0
        private static int PingPong_OtherProcess(string inName, string outName)
        {
            // Create pipes with the supplied names
            using (var inbound = new NamedPipeClientStream(".", inName, PipeDirection.In))
            using (var outbound = new NamedPipeServerStream(outName, PipeDirection.Out))
            {
                // Wait for the connections to be established
                Task.WaitAll(inbound.ConnectAsync(), outbound.WaitForConnectionAsync());

                // Repeatedly read then write bytes from and to the other process
                for (int i = 0; i < 10; i++)
                {
                    int b = inbound.ReadByte();
                    outbound.WriteByte((byte)b);
                }
            }
            return SuccessExitCode;
        }
Ejemplo n.º 4
0
        public void PingPong()
        {
            // Create names for two pipes
            string outName = Guid.NewGuid().ToString("N");
            string inName = Guid.NewGuid().ToString("N");

            // Create the two named pipes, one for each direction, then create
            // another process with which to communicate
            using (var outbound = new NamedPipeServerStream(outName, PipeDirection.Out))
            using (var inbound = new NamedPipeClientStream(".", inName, PipeDirection.In))
            using (var remote = RemoteInvoke(PingPong_OtherProcess, outName, inName))
            {
                // Wait for both pipes to be connected
                Task.WaitAll(outbound.WaitForConnectionAsync(), inbound.ConnectAsync());

                // Repeatedly write then read a byte to and from the other process
                for (byte i = 0; i < 10; i++)
                {
                    outbound.WriteByte(i);
                    int received = inbound.ReadByte();
                    Assert.Equal(i, received);
                }
            }
        }
Ejemplo n.º 5
0
        public async Task NamedPipeReadViaAsyncFileStream(bool asyncReads)
        {
            string name = Guid.NewGuid().ToString("N");
            using (var server = new NamedPipeServerStream(name, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
            {
                Task serverTask = Task.Run(async () =>
                {
                    await server.WaitForConnectionAsync();
                    await server.WriteAsync(new byte[] { 0, 1, 2, 3, 4, 5 }, 0, 6);
                });

                WaitNamedPipeW(@"\\.\pipe\" + name, -1);
                using (SafeFileHandle clientHandle = CreateFileW(@"\\.\pipe\" + name, GENERIC_READ, FileShare.None, IntPtr.Zero, FileMode.Open, (int)PipeOptions.Asynchronous, IntPtr.Zero))
                using (var client = new FileStream(clientHandle, FileAccess.Read, bufferSize: 3, isAsync: true))
                {
                    var arr = new byte[1];
                    for (int i = 0; i < 6; i++)
                    {
                        Assert.Equal(1, asyncReads ?
                            await client.ReadAsync(arr, 0, 1) :
                            client.Read(arr, 0, 1));
                        Assert.Equal(i, arr[0]);
                    }
                }

                await serverTask;
            }
        }
Ejemplo n.º 6
0
        private Task RunAsync(string mutexId, string pipeId,
            CancellationTokenSource cancellationTokenSource)
        {
            var cancellationToken = cancellationTokenSource.Token;
            return Task.Run(async () =>
            {
                try
                {
                    using (var mutex = new Mutex(false, mutexId))
                    {
                        //ミューテックスの所有権を要求する
                        if (!mutex.WaitOne(0, false))
                        {
                            //すでに起動していると判断して終了
                            return;
                        }


                        try
                        {
                            //mutexDictionary.TryAdd(mutexId, mutex);

                            while (true)
                            {
                                cancellationToken.ThrowIfCancellationRequested();

                                using (var pipeServer =
                                    new NamedPipeServerStream(pipeId, PipeDirection.In))
                                {
                                    // Wait for a client to connect
                                    await pipeServer.WaitForConnectionAsync(cancellationToken);

                                    try
                                    {
                                        using (var sr = new StreamReader(pipeServer))
                                        {
                                            while (pipeServer.IsConnected)
                                            {
                                                var text = sr.ReadLine();
                                                if (text != null)
                                                {
                                                    this.LineReceivedSubject.OnNext(text);
                                                }
                                                cancellationToken.ThrowIfCancellationRequested();
                                            }
                                        }
                                    }
                                    catch (IOException e)
                                    {
                                        // Catch the IOException that is raised if the pipe is broken
                                        // or disconnected.
                                    }
                                }
                            }
                        }
                        finally
                        {
                            mutex.ReleaseMutex();
                            mutex.Close();
                        }
                    }
                }
                catch (Exception e)
                {
                    this.LineReceivedSubject.OnError(e);
                }
            }, cancellationToken);
        }
Ejemplo n.º 7
0
        public async Task NamedPipeViaFileStream_CancellationRequested_OperationCanceled()
        {
            string name = Guid.NewGuid().ToString("N");
            using (var server = new NamedPipeServerStream(name, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
            {
                Task serverTask = server.WaitForConnectionAsync();

                Assert.True(WaitNamedPipeW(@"\\.\pipe\" + name, -1));
                using (SafeFileHandle clientHandle = CreateFileW(@"\\.\pipe\" + name, GENERIC_READ, FileShare.None, IntPtr.Zero, FileMode.Open, (int)PipeOptions.Asynchronous, IntPtr.Zero))
                using (var client = new FileStream(clientHandle, FileAccess.Read, bufferSize: 3, isAsync: true))
                {
                    await serverTask;

                    var cts = new CancellationTokenSource();
                    Task clientTask = client.CopyToAsync(new MemoryStream(), 0x1000, cts.Token);
                    Assert.False(clientTask.IsCompleted);

                    cts.Cancel();
                    await Assert.ThrowsAsync<OperationCanceledException>(() => clientTask);
                }
            }
        }
Ejemplo n.º 8
0
        public async Task NamedPipeViaFileStream_AllDataCopied(bool useAsync, int writeSize, int numWrites)
        {
            long totalLength = writeSize * numWrites;
            var expectedData = new byte[totalLength];
            new Random(42).NextBytes(expectedData);

            var results = new MemoryStream();
            var pipeOptions = useAsync ? PipeOptions.Asynchronous : PipeOptions.None;

            string name = Guid.NewGuid().ToString("N");
            using (var server = new NamedPipeServerStream(name, PipeDirection.Out, 1, PipeTransmissionMode.Byte, pipeOptions))
            {
                Task serverTask = Task.Run(async () =>
                {
                    await server.WaitForConnectionAsync();
                    for (int i = 0; i < numWrites; i++)
                    {
                        await server.WriteAsync(expectedData, i * writeSize, writeSize);
                    }
                    server.Dispose();
                });

                Assert.True(WaitNamedPipeW(@"\\.\pipe\" + name, -1));
                using (SafeFileHandle clientHandle = CreateFileW(@"\\.\pipe\" + name, GENERIC_READ, FileShare.None, IntPtr.Zero, FileMode.Open, (int)pipeOptions, IntPtr.Zero))
                using (var client = new FileStream(clientHandle, FileAccess.Read, bufferSize: 3, isAsync: useAsync))
                {
                    Task copyTask = client.CopyToAsync(results, (int)totalLength);
                    await await Task.WhenAny(serverTask, copyTask);
                    await copyTask;
                }
            }

            byte[] actualData = results.ToArray();
            Assert.Equal(expectedData.Length, actualData.Length);
            Assert.Equal<byte>(expectedData, actualData);
        }
Ejemplo n.º 9
0
        private async Task ConnectToBrokerWorker() {
            Trace.Assert(_brokerProcess == null);

            string rhostBrokerExe = Path.Combine(_rhostDirectory, RHostBrokerExe);
            if (!_services.FileSystem.FileExists(rhostBrokerExe)) {
                throw new RHostBrokerBinaryMissingException();
            }

            Process process = null;
            try {
                string pipeName = Guid.NewGuid().ToString();

                using (var serverUriPipe = new NamedPipeServerStream(pipeName, PipeDirection.In)) {
                    var psi = new ProcessStartInfo {
                        FileName = rhostBrokerExe,
                        UseShellExecute = false,
                        Arguments =
                            $" --logging:logHostOutput {Log.LogVerbosity >= LogVerbosity.Normal}" +
                            $" --logging:logPackets {Log.LogVerbosity == LogVerbosity.Traffic}" +
                            $" --server.urls http://127.0.0.1:0" + // :0 means first available ephemeral port
                            $" --startup:name \"{Name}\"" +
                            $" --startup:writeServerUrlsToPipe {pipeName}" +
                            $" --lifetime:parentProcessId {Process.GetCurrentProcess().Id}" +
                            $" --security:secret \"{_credentials.Password}\"" +
                            $" --R:autoDetect false" +
                            $" --R:interpreters:{InterpreterId}:name \"{Name}\"" +
                            $" --R:interpreters:{InterpreterId}:basePath \"{_rHome.TrimTrailingSlash()}\""
                    };

                    if (!ShowConsole) {
                        psi.CreateNoWindow = true;
                    }

                    process = StartBroker(psi);
                    process.EnableRaisingEvents = true;

                    var cts = new CancellationTokenSource(100000);
                    process.Exited += delegate {
                        cts.Cancel();
                        _brokerProcess = null;
                        _connectLock.EnqueueReset();
                    };

                    await serverUriPipe.WaitForConnectionAsync(cts.Token);

                    var serverUriData = new MemoryStream();
                    try {
                        // Pipes are special in that a zero-length read is not an indicator of end-of-stream.
                        // Stream.CopyTo uses a zero-length read as indicator of end-of-stream, so it cannot 
                        // be used here. Instead, copy the data manually, using PipeStream.IsConnected to detect
                        // when the other side has finished writing and closed the pipe.
                        var buffer = new byte[0x1000];
                        do {
                            int count = await serverUriPipe.ReadAsync(buffer, 0, buffer.Length, cts.Token);
                            serverUriData.Write(buffer, 0, count);
                        } while (serverUriPipe.IsConnected);
                    } catch (OperationCanceledException) {
                        throw new RHostDisconnectedException("Timed out while waiting for broker process to report its endpoint URI");
                    }

                    string serverUriStr = Encoding.UTF8.GetString(serverUriData.ToArray());
                    Uri[] serverUri;
                    try {
                        serverUri = Json.DeserializeObject<Uri[]>(serverUriStr);
                    } catch (JsonSerializationException ex) {
                        throw new RHostDisconnectedException($"Invalid JSON for endpoint URIs received from broker ({ex.Message}): {serverUriStr}");
                    }
                    if (serverUri?.Length != 1) {
                        throw new RHostDisconnectedException($"Unexpected number of endpoint URIs received from broker: {serverUriStr}");
                    }

                    CreateHttpClient(serverUri[0]);
                }

                if (DisposableBag.TryAdd(DisposeBrokerProcess)) {
                    _brokerProcess = process;
                }
            } finally {
                if (_brokerProcess == null) {
                    try {
                        process?.Kill();
                    } catch (Exception) {
                    } finally {
                        process?.Dispose();
                    }
                }
            }
        }
Ejemplo n.º 10
0
    public static async Task ClientCloneTests()
    {
        const string pipeName = "fooClientclone";

        byte[] msg1 = new byte[] { 5, 7, 9, 10 };
        byte[] received0 = new byte[] { };
        byte[] received1 = new byte[] { 0, 0, 0, 0 };

        using (NamedPipeServerStream server = new NamedPipeServerStream(pipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte))
        using (NamedPipeClientStream clientBase = new NamedPipeClientStream(".", pipeName, PipeDirection.Out, PipeOptions.None))
        {
            await Task.WhenAll(server.WaitForConnectionAsync(), clientBase.ConnectAsync());

            using (NamedPipeClientStream client = new NamedPipeClientStream(PipeDirection.Out, false, true, clientBase.SafePipeHandle))
            {
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    Assert.Equal(1, client.NumberOfServerInstances);
                }
                Assert.Equal(PipeTransmissionMode.Byte, client.TransmissionMode);

                Task clientTask = Task.Run(() => client.Write(msg1, 0, msg1.Length));
                int len1 = server.Read(received1, 0, msg1.Length);
                await clientTask;
                Assert.Equal(msg1.Length, len1);
                Assert.Equal(msg1, received1);

                // test special cases of buffer lengths = 0
                int len0 = server.Read(received0, 0, 0);
                Assert.Equal(0, len0);
                Assert.Equal(0, await server.ReadAsync(received0, 0, 0));
            }
        }
    }
Ejemplo n.º 11
0
    public static async Task ClientServerOneWayOperations(
        string pipeName, PipeDirection serverDirection,
        bool asyncServerPipe, bool asyncClientPipe,
        bool asyncServerOps, bool asyncClientOps)
    {
        PipeDirection clientDirection = serverDirection == PipeDirection.Out ? PipeDirection.In : PipeDirection.Out;
        PipeOptions serverOptions = asyncServerPipe ? PipeOptions.Asynchronous : PipeOptions.None;
        PipeOptions clientOptions = asyncClientPipe ? PipeOptions.Asynchronous : PipeOptions.None;

        using (NamedPipeServerStream server = new NamedPipeServerStream(pipeName, serverDirection, 1, PipeTransmissionMode.Byte, serverOptions))
        {
            byte[] received = new byte[] { 0 };
            Task clientTask = Task.Run(async () =>
            {
                using (NamedPipeClientStream client = new NamedPipeClientStream(".", pipeName, clientDirection, clientOptions))
                {
                    if (asyncClientOps)
                    {
                        await client.ConnectAsync();
                        if (clientDirection == PipeDirection.In)
                        {
                            received = await ReadBytesAsync(client, sendBytes.Length);
                        }
                        else
                        {
                            await WriteBytesAsync(client, sendBytes);
                        }
                    }
                    else
                    {
                        client.Connect();
                        if (clientDirection == PipeDirection.In)
                        {
                            received = ReadBytes(client, sendBytes.Length);
                        }
                        else
                        {
                            WriteBytes(client, sendBytes);
                        }
                    }
                }
            });

            if (asyncServerOps)
            {
                await server.WaitForConnectionAsync();
                if (serverDirection == PipeDirection.Out)
                {
                    await WriteBytesAsync(server, sendBytes);
                }
                else
                {
                    received = await ReadBytesAsync(server, sendBytes.Length);
                }
            }
            else {
                server.WaitForConnection();
                if (serverDirection == PipeDirection.Out)
                {
                    WriteBytes(server, sendBytes);
                }
                else
                {
                    received = ReadBytes(server, sendBytes.Length);
                }
            }

            await clientTask;
            Assert.Equal(sendBytes, received);

            server.Disconnect();
            Assert.False(server.IsConnected);
        }
    }
Ejemplo n.º 12
0
        private static async Task<int> CreateServerFailsConnectionCore(string pipeName, CancellationToken cancellationToken)
        {
            var connections = 0;
            try
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    using (var pipeStream = new NamedPipeServerStream(pipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
                    {
                        await pipeStream.WaitForConnectionAsync(cancellationToken);
                        connections++;
                    }
                }
            }
            catch (Exception)
            {
                // Exceptions are okay and expected here
            }

            return connections;
        }
Ejemplo n.º 13
0
            public override async Task<IAsyncTransport> CreateAsync(Address address)
            {
                NamedPipeServerStream server = new NamedPipeServerStream(address.Path, PipeDirection.InOut, 4,
                    PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
#if DOTNET
                await server.WaitForConnectionAsync();
#else
                await Task.Factory.FromAsync(
                    (c, s) => server.BeginWaitForConnection(c, s),
                    (r) => server.EndWaitForConnection(r),
                    null);
#endif
                return new NamedPipeTransport(server);
            }
        public async Task<Tuple<Int32, string>> ListenerAcceptAsync(
            int listenerId
        )
        {
            // Get the listener (which is just a pipe name)
            // TODO: I guess that technically we should do some sort of check to
            // make sure that no connections are being accepted on this
            // endpoint.  Perhaps change listener map to add cancellation token?
            string pipeName = null;
            lock (this)
            {
                if (!_listeners.TryGetValue(listenerId, out pipeName))
                {
                    return Tuple.Create(0, "invalid listener id");
                }
            }

            // Create the connection
            // NOTE: It is essential that the PipeOptions.Asynchronous option be
            // specified, or the ReadAsync and WriteAsync methods will block
            // (and I don't mean they'll call await and halt - I mean they'll
            // never return a Task object)
            var connection = new NamedPipeServerStream(
                pipeName,
                PipeDirection.InOut,
                NamedPipeServerStream.MaxAllowedServerInstances,
                PipeTransmissionMode.Byte,
                PipeOptions.Asynchronous
            );

            // Try to accept a connection asynchronously
            try
            {
                await connection.WaitForConnectionAsync();
            }
            catch (Exception e)
            {
                return Tuple.Create(-1, e.Message);
            }

            // Store the connection
            Int32 connectionId = -1;
            lock (this)
            {
                // Compute the next connection id.  Watch for overflow, because
                // we use -1 as the invalid identifier.
                if (_nextConnectionId < 0)
                {
                    connection.Close();
                    return Tuple.Create(-1, "connection ids exhausted");
                }
                connectionId = _nextConnectionId++;

                // Do the storage
                _connections[connectionId] = connection;
            }

            // All done
            return Tuple.Create(connectionId, "");
        }