예제 #1
0
        private async void Consume(IPipeReader input)
        {
            while (true)
            {
                var result = await input.ReadAsync();

                var buffer = result.Buffer;

                try
                {
                    if (buffer.IsEmpty && result.IsCompleted)
                    {
                        break;
                    }

                    await WriteAsync(buffer);
                }
                finally
                {
                    input.Advance(buffer.End);
                }
            }

            input.Complete();
        }
        public static async void Echo(IPipeReader input, IPipeWriter output)
        {
            try
            {
                while (true)
                {
                    var result = await input.ReadAsync();

                    var request = result.Buffer;

                    if (request.IsEmpty && result.IsCompleted)
                    {
                        input.Advance(request.End);
                        break;
                    }

                    int len      = request.Length;
                    var response = output.Alloc();
                    response.Append(request);
                    await response.FlushAsync();

                    input.Advance(request.End);
                }
            }
            catch
            {
                input.Complete();
                output.Complete();
            }
        }
예제 #3
0
            public async Task Execute(IPipeReader reader, IPipeWriter writer)
            {
                List <MemoryHandle> handles = new List <MemoryHandle>();

                while (true)
                {
                    var result = await reader.ReadAsync();

                    var inputBuffer = result.Buffer;

                    if (inputBuffer.IsEmpty)
                    {
                        if (result.IsCompleted)
                        {
                            break;
                        }

                        reader.Advance(inputBuffer.End);
                        continue;
                    }

                    var writerBuffer = writer.Alloc();
                    var buffer       = inputBuffer.First;
                    if (buffer.Length > 0)
                    {
                        unsafe
                        {
                            var handle = buffer.Retain(pin: true);
                            handles.Add(handle);
                            _inflater.SetInput((IntPtr)handle.PinnedPointer, buffer.Length);

                            writerBuffer.Ensure();
                            handle = writerBuffer.Buffer.Retain(pin: true);
                            handles.Add(handle);
                            int written = _inflater.Inflate((IntPtr)handle.PinnedPointer, writerBuffer.Buffer.Length);
                            writerBuffer.Advance(written);

                            var consumed = buffer.Length - _inflater.AvailableInput;

                            inputBuffer = inputBuffer.Slice(0, consumed);
                        }
                    }

                    reader.Advance(inputBuffer.End);

                    await writerBuffer.FlushAsync();
                }

                reader.Complete();

                writer.Complete();

                _inflater.Dispose();

                foreach (var handle in handles)
                {
                    handle.Dispose();
                }
            }
        private async Task WriteOutputAsync(LibuvOutputConsumer consumer, IPipeReader outputReader, Frame frame)
        {
            // This WriteOutputAsync() calling code is equivalent to that in LibuvConnection.
            try
            {
                // Ensure that outputReader.Complete() runs on the LibuvThread.
                // Without ConfigureAwait(false), xunit will dispatch.
                await consumer.WriteOutputAsync().ConfigureAwait(false);

                frame.Abort(error: null);
                outputReader.Complete();
            }
            catch (UvException ex)
            {
                frame.Abort(ex);
                outputReader.Complete(ex);
            }
        }
예제 #5
0
        private async Task ReadInputAsync(Stream stream)
        {
            Exception error = null;

            try
            {
                if (stream == null)
                {
                    // REVIEW: Do we need an exception here?
                    return;
                }

                while (true)
                {
                    var outputBuffer = Input.Writer.Alloc(MinAllocBufferSize);

                    var array = outputBuffer.Buffer.GetArray();
                    try
                    {
                        var bytesRead = await stream.ReadAsync(array.Array, array.Offset, array.Count);

                        outputBuffer.Advance(bytesRead);

                        if (bytesRead == 0)
                        {
                            // FIN
                            break;
                        }
                    }
                    finally
                    {
                        outputBuffer.Commit();
                    }

                    var result = await outputBuffer.FlushAsync();

                    if (result.IsCompleted)
                    {
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                // Don't rethrow the exception. It should be handled by the Pipeline consumer.
                error = ex;
            }
            finally
            {
                Input.Writer.Complete(error);
                // The application could have ended the input pipe so complete
                // the transport pipe as well
                _transportInputPipeReader.Complete();
            }
        }
 public static async Task CopyToEndAsync(this IPipeReader input, Stream stream, int bufferSize, CancellationToken cancellationToken)
 {
     try
     {
         await input.CopyToAsync(stream, bufferSize, cancellationToken);
     }
     catch (Exception ex)
     {
         input.Complete(ex);
         return;
     }
     return;
 }
예제 #7
0
        private static async void WriteToSocket(TSocket tsocket, IPipeReader reader)
        {
            Exception error = null;

            try
            {
                while (true)
                {
                    var readResult = await reader.ReadAsync();

                    ReadableBuffer buffer = readResult.Buffer;
                    ReadCursor     end    = buffer.Start;
                    try
                    {
                        if ((buffer.IsEmpty && readResult.IsCompleted) || readResult.IsCancelled)
                        {
                            // EOF or TransportThread stopped
                            break;
                        }
                        if (!buffer.IsEmpty)
                        {
                            var result = TrySend(tsocket.Fd, ref buffer);
                            if (result.Value == buffer.Length)
                            {
                                end = buffer.End;
                            }
                            else if (result.IsSuccess)
                            {
                                end = buffer.Move(buffer.Start, result.Value);
                            }
                            else if (result == PosixResult.EAGAIN || result == PosixResult.EWOULDBLOCK)
                            {
                                if (!await Writable(tsocket))
                                {
                                    // TransportThread stopped
                                    break;
                                }
                            }
                            else
                            {
                                error = result.AsException();
                                break;
                            }
                        }
                    }
                    finally
                    {
                        // We need to call Advance to end the read
                        reader.Advance(end);
                    }
                }
            }
            catch (Exception ex)
            {
                error = ex;
            }
            finally
            {
                tsocket.ConnectionContext.OnConnectionClosed(error);
                reader.Complete(error);

                tsocket.StopReadFromSocket();

                CleanupSocketEnd(tsocket);
            }
        }
예제 #8
0
            public async Task Execute(IPipeReader reader, IPipeWriter writer)
            {
                List <MemoryHandle> handles = new List <MemoryHandle>();

                while (true)
                {
                    var result = await reader.ReadAsync();

                    var inputBuffer = result.Buffer;

                    if (inputBuffer.IsEmpty)
                    {
                        if (result.IsCompleted)
                        {
                            break;
                        }

                        reader.Advance(inputBuffer.End);
                        continue;
                    }

                    var writerBuffer = writer.Alloc();
                    var buffer       = inputBuffer.First;

                    unsafe
                    {
                        var handle = buffer.Retain(pin: true);
                        handles.Add(handle);
                        _deflater.SetInput((IntPtr)handle.PinnedPointer, buffer.Length);
                    }

                    while (!_deflater.NeedsInput())
                    {
                        unsafe
                        {
                            writerBuffer.Ensure();
                            var handle = writerBuffer.Buffer.Retain(pin: true);
                            handles.Add(handle);
                            int written = _deflater.ReadDeflateOutput((IntPtr)handle.PinnedPointer, writerBuffer.Buffer.Length);
                            writerBuffer.Advance(written);
                        }
                    }

                    var consumed = buffer.Length - _deflater.AvailableInput;

                    inputBuffer = inputBuffer.Slice(0, consumed);

                    reader.Advance(inputBuffer.End);

                    await writerBuffer.FlushAsync();
                }

                bool flushed = false;

                do
                {
                    // Need to do more stuff here
                    var writerBuffer = writer.Alloc();

                    unsafe
                    {
                        writerBuffer.Ensure();
                        var memory = writerBuffer.Buffer;
                        var handle = memory.Retain(pin: true);
                        handles.Add(handle);
                        int compressedBytes;
                        flushed = _deflater.Flush((IntPtr)handle.PinnedPointer, memory.Length, out compressedBytes);
                        writerBuffer.Advance(compressedBytes);
                    }

                    await writerBuffer.FlushAsync();
                }while (flushed);

                bool finished = false;

                do
                {
                    // Need to do more stuff here
                    var writerBuffer = writer.Alloc();

                    unsafe
                    {
                        writerBuffer.Ensure();
                        var memory = writerBuffer.Buffer;
                        var handle = memory.Retain(pin: true);
                        handles.Add(handle);
                        int compressedBytes;
                        finished = _deflater.Finish((IntPtr)handle.PinnedPointer, memory.Length, out compressedBytes);
                        writerBuffer.Advance(compressedBytes);
                    }

                    await writerBuffer.FlushAsync();
                }while (!finished);

                reader.Complete();

                writer.Complete();

                _deflater.Dispose();

                foreach (var handle in handles)
                {
                    handle.Dispose();
                }
            }
예제 #9
0
        private async Task DoSend()
        {
            Exception error = null;

            try
            {
                while (true)
                {
                    // Wait for data to write from the pipe producer
                    var result = await _output.ReadAsync();

                    var buffer = result.Buffer;

                    if (result.IsCancelled)
                    {
                        break;
                    }

                    try
                    {
                        if (!buffer.IsEmpty)
                        {
                            if (buffer.IsSingleSpan)
                            {
                                await _socket.SendAsync(GetArraySegment(buffer.First), SocketFlags.None);
                            }
                            else
                            {
                                SetupSendBuffers(buffer);

                                try
                                {
                                    await _socket.SendAsync(_sendBufferList, SocketFlags.None);
                                }
                                finally
                                {
                                    _sendBufferList.Clear();
                                }
                            }
                        }
                        else if (result.IsCompleted)
                        {
                            break;
                        }
                    }
                    finally
                    {
                        _output.Advance(buffer.End);
                    }
                }

                _socket.Shutdown(SocketShutdown.Send);
            }
            catch (SocketException ex) when(ex.SocketErrorCode == SocketError.OperationAborted)
            {
                error = null;
            }
            catch (ObjectDisposedException)
            {
                error = null;
            }
            catch (IOException ex)
            {
                error = ex;
            }
            catch (Exception ex)
            {
                error = new IOException(ex.Message, ex);
            }
            finally
            {
                _connectionContext.OnConnectionClosed(error);
                _output.Complete(error);
            }
        }
            public async Task Execute(IPipeReader reader, IPipeWriter writer)
            {
                while (true)
                {
                    var result = await reader.ReadAsync();

                    var inputBuffer = result.Buffer;

                    if (inputBuffer.IsEmpty)
                    {
                        if (result.IsCompleted)
                        {
                            break;
                        }

                        reader.Advance(inputBuffer.End);
                        continue;
                    }

                    var writerBuffer = writer.Alloc();
                    var memory       = inputBuffer.First;

                    unsafe
                    {
                        // TODO: Pin pointer if not pinned
                        void *inPointer;
                        if (memory.TryGetPointer(out inPointer))
                        {
                            _deflater.SetInput((IntPtr)inPointer, memory.Length);
                        }
                        else
                        {
                            throw new InvalidOperationException("Pointer needs to be pinned");
                        }
                    }

                    while (!_deflater.NeedsInput())
                    {
                        unsafe
                        {
                            void *outPointer;
                            writerBuffer.Ensure();
                            if (writerBuffer.Memory.TryGetPointer(out outPointer))
                            {
                                int written = _deflater.ReadDeflateOutput((IntPtr)outPointer, writerBuffer.Memory.Length);
                                writerBuffer.Advance(written);
                            }
                            else
                            {
                                throw new InvalidOperationException("Pointer needs to be pinned");
                            }
                        }
                    }

                    var consumed = memory.Length - _deflater.AvailableInput;

                    inputBuffer = inputBuffer.Slice(0, consumed);

                    reader.Advance(inputBuffer.End);

                    await writerBuffer.FlushAsync();
                }

                bool flushed = false;

                do
                {
                    // Need to do more stuff here
                    var writerBuffer = writer.Alloc();

                    unsafe
                    {
                        void *pointer;
                        writerBuffer.Ensure();
                        var memory = writerBuffer.Memory;
                        if (memory.TryGetPointer(out pointer))
                        {
                            int compressedBytes;
                            flushed = _deflater.Flush((IntPtr)pointer, memory.Length, out compressedBytes);
                            writerBuffer.Advance(compressedBytes);
                        }
                        else
                        {
                            throw new InvalidOperationException("Pointer needs to be pinned");
                        }
                    }

                    await writerBuffer.FlushAsync();
                }while (flushed);

                bool finished = false;

                do
                {
                    // Need to do more stuff here
                    var writerBuffer = writer.Alloc();

                    unsafe
                    {
                        void *pointer;
                        writerBuffer.Ensure();
                        var memory = writerBuffer.Memory;
                        if (memory.TryGetPointer(out pointer))
                        {
                            int compressedBytes;
                            finished = _deflater.Finish((IntPtr)pointer, memory.Length, out compressedBytes);
                            writerBuffer.Advance(compressedBytes);
                        }
                    }

                    await writerBuffer.FlushAsync();
                }while (!finished);

                reader.Complete();

                writer.Complete();

                _deflater.Dispose();
            }
            public async Task Execute(IPipeReader reader, IPipeWriter writer)
            {
                while (true)
                {
                    var result = await reader.ReadAsync();

                    var inputBuffer = result.Buffer;

                    if (inputBuffer.IsEmpty)
                    {
                        if (result.IsCompleted)
                        {
                            break;
                        }

                        reader.Advance(inputBuffer.End);
                        continue;
                    }

                    var writerBuffer = writer.Alloc();
                    var memory       = inputBuffer.First;
                    if (memory.Length > 0)
                    {
                        unsafe
                        {
                            void *pointer;
                            if (memory.TryGetPointer(out pointer))
                            {
                                _inflater.SetInput((IntPtr)pointer, memory.Length);

                                void *writePointer;
                                writerBuffer.Ensure();
                                if (writerBuffer.Memory.TryGetPointer(out writePointer))
                                {
                                    int written = _inflater.Inflate((IntPtr)writePointer, writerBuffer.Memory.Length);
                                    writerBuffer.Advance(written);
                                }
                                else
                                {
                                    throw new InvalidOperationException("Pointer needs to be pinned");
                                }
                            }
                            else
                            {
                                throw new InvalidOperationException("Pointer needs to be pinned");
                            }

                            var consumed = memory.Length - _inflater.AvailableInput;

                            inputBuffer = inputBuffer.Slice(0, consumed);
                        }
                    }

                    reader.Advance(inputBuffer.End);

                    await writerBuffer.FlushAsync();
                }

                reader.Complete();

                writer.Complete();

                _inflater.Dispose();
            }