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();
            }
        }
Exemplo n.º 2
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();
                }
            }
Exemplo n.º 3
0
        public static async Task CopyToAsync(this IPipeReader input, IPipeWriter output)
        {
            while (true)
            {
                var result = await input.ReadAsync();

                var inputBuffer = result.Buffer;

                try
                {
                    if (inputBuffer.IsEmpty && result.IsCompleted)
                    {
                        return;
                    }

                    var buffer = output.Alloc();

                    foreach (var memory in inputBuffer)
                    {
                        buffer.Write(memory.Span);
                    }


                    await buffer.FlushAsync();
                }
                finally
                {
                    input.Advance(inputBuffer.End);
                }
            }
        }
Exemplo n.º 4
0
        public static ValueTask <int> ReadAsync(this IPipeReader input, ArraySegment <byte> destination)
        {
            while (true)
            {
                var awaiter = input.ReadAsync();

                if (!awaiter.IsCompleted)
                {
                    break;
                }

                var result      = awaiter.GetResult();
                var inputBuffer = result.Buffer;

                var length = (int)Math.Min(inputBuffer.Length, destination.Count);

                var sliced = inputBuffer.Slice(0, length);
                sliced.CopyTo(destination);

                input.Advance(sliced.End);

                if (length != 0)
                {
                    return(new ValueTask <int>(length));
                }

                if (result.IsCompleted)
                {
                    return(new ValueTask <int>(0));
                }
            }

            return(new ValueTask <int>(input.ReadAsyncAwaited(destination)));
        }
Exemplo n.º 5
0
 public static IObservable <ReadOnlyMemory <byte> > CreateObservable(this PipeFactory pfac, IPipeReader reader)
 {
     return(Observable.Create <ReadOnlyMemory <byte> >(async(ob, ct) =>
     {
         try
         {
             while (true)
             {
                 ct.ThrowIfCancellationRequested();
                 var result = await reader.ReadAsync();
                 if (result.IsCancelled || (result.IsCompleted && result.Buffer.IsEmpty))
                 {
                     break;
                 }
                 foreach (var rbuf in result.Buffer)
                 {
                     ob.OnNext(rbuf);
                 }
                 reader.Advance(result.Buffer.End);
             }
             ob.OnCompleted();
         }
         catch (Exception e)
         {
             try
             {
                 reader.CancelPendingRead();
             }
             catch
             {
             }
             ob.OnError(e);
         }
     }));
 }
Exemplo n.º 6
0
        private async Task <int> ReadAsync(ArraySegment <byte> buffer)
        {
            while (true)
            {
                var result = await _input.ReadAsync();

                var readableBuffer = result.Buffer;
                try
                {
                    if (!readableBuffer.IsEmpty)
                    {
                        var count = Math.Min(readableBuffer.Length, buffer.Count);
                        readableBuffer = readableBuffer.Slice(0, count);
                        readableBuffer.CopyTo(buffer);
                        return(count);
                    }
                    else if (result.IsCompleted)
                    {
                        return(0);
                    }
                }
                finally
                {
                    _input.Advance(readableBuffer.End, readableBuffer.End);
                }
            }
        }
        public static async Task CopyToAsync(this IPipeReader input, IPipeWriter output)
        {
            while (true)
            {
                var result = await input.ReadAsync();

                var inputBuffer = result.Buffer;

                var fin = result.IsCompleted;

                try
                {
                    if (inputBuffer.IsEmpty && fin)
                    {
                        return;
                    }

                    var buffer = output.Alloc();

                    buffer.Append(inputBuffer);

                    await buffer.FlushAsync();
                }
                finally
                {
                    input.Advance(inputBuffer.End);
                }
            }
        }
        private static async Task <int> ReadAsyncAwaited(this IPipeReader input, Span <byte> destination)
        {
            while (true)
            {
                var result = await input.ReadAsync();

                var inputBuffer = result.Buffer;

                var fin = result.IsCompleted;

                var sliced = inputBuffer.Slice(0, Math.Min(inputBuffer.Length, destination.Length));
                sliced.CopyTo(destination);
                int actual = sliced.Length;
                input.Advance(sliced.End);

                if (actual != 0)
                {
                    return(actual);
                }
                else if (fin)
                {
                    return(0);
                }
            }
        }
        public static ValueTask <int> ReadAsync(this IPipeReader input, Span <byte> destination)
        {
            while (true)
            {
                var awaiter = input.ReadAsync();

                if (!awaiter.IsCompleted)
                {
                    break;
                }

                var result      = awaiter.GetResult();
                var inputBuffer = result.Buffer;

                var fin    = result.IsCompleted;
                var sliced = inputBuffer.Slice(0, Math.Min(inputBuffer.Length, destination.Length));
                sliced.CopyTo(destination);
                int actual = sliced.Length;
                input.Advance(sliced.End);

                if (actual != 0)
                {
                    return(new ValueTask <int>(actual));
                }
                else if (fin)
                {
                    return(new ValueTask <int>(0));
                }
            }

            return(new ValueTask <int>(input.ReadAsyncAwaited(destination)));
        }
Exemplo n.º 10
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();
        }
Exemplo n.º 11
0
        protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context)
        {
            long remaining = ContentLength;

            while (remaining > 0)
            {
                var result = await _output.ReadAsync();

                var inputBuffer = result.Buffer;

                var fin = result.IsCompleted;

                var consumed = inputBuffer.Start;

                try
                {
                    if (inputBuffer.IsEmpty && fin)
                    {
                        return;
                    }

                    var data = inputBuffer.Slice(0, remaining);

                    foreach (var memory in data)
                    {
                        ArraySegment <byte> buffer;

                        unsafe
                        {
                            if (!memory.TryGetArray(out buffer))
                            {
                                // Fall back to copies if this was native memory and we were unable to get
                                //  something we could write
                                buffer = new ArraySegment <byte>(memory.Span.ToArray());
                            }
                        }

                        await stream.WriteAsync(buffer.Array, buffer.Offset, buffer.Count);
                    }

                    consumed   = data.End;
                    remaining -= data.Length;
                }
                finally
                {
                    _output.Advance(consumed);
                }
            }
        }
Exemplo n.º 12
0
        public static async Task <ReadableBuffer> ReadToEndAsync(this IPipeReader input)
        {
            while (true)
            {
                // Wait for more data
                var result = await input.ReadAsync();

                if (result.IsCompleted)
                {
                    // Read all the data, return it
                    return(result.Buffer);
                }

                // Don't advance the buffer so remains in buffer
                input.Advance(result.Buffer.Start, result.Buffer.End);
            }
        }
Exemplo n.º 13
0
 public void WriteRecords(IPipeReader pipeReader, RecordType recordType)
 {
     lock (_connectionOutputLock)
     {
         if (!pipeReader.TryRead(out var reader))
         {
             return;
         }
         var buffer = reader.Buffer;
         var output = _output.Alloc();
         try
         {
             WriteRecords(ref buffer, ref output, recordType);
         }
         finally
         {
             pipeReader.Advance(buffer.End);
         }
         output.Commit();
     }
 }
Exemplo n.º 14
0
        private async Task CopyCompletedAsync(IPipeReader input, IPipeWriter output)
        {
            var result = await input.ReadAsync();

            var inputBuffer = result.Buffer;

            while (true)
            {
                try
                {
                    if (inputBuffer.IsEmpty && result.IsCompleted)
                    {
                        return;
                    }

                    var buffer = output.Alloc();
                    foreach (var memory in inputBuffer)
                    {
                        buffer.Write(memory.Span);
                    }
                    await buffer.FlushAsync();
                }
                finally
                {
                    input.Advance(inputBuffer.End);
                }

                var awaiter = input.ReadAsync();

                if (!awaiter.IsCompleted)
                {
                    // No more data
                    break;
                }

                result = await input.ReadAsync();

                inputBuffer = result.Buffer;
            }
        }
Exemplo n.º 15
0
        private static async Task CopyCompletedAsync(IPipeReader input, IPipeWriter output)
        {
            var result = await input.ReadAsync();

            var inputBuffer = result.Buffer;

            while (true)
            {
                try
                {
                    if (inputBuffer.IsEmpty && result.IsCompleted)
                    {
                        return;
                    }

                    var buffer = output.Alloc();

                    buffer.Append(inputBuffer);

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

                var awaiter = input.ReadAsync();

                if (!awaiter.IsCompleted)
                {
                    // No more data
                    break;
                }

                result = await input.ReadAsync();

                inputBuffer = result.Buffer;
            }
        }
Exemplo n.º 16
0
        public static async Task CopyToAsync(this IPipeReader input, Stream stream, int bufferSize, CancellationToken cancellationToken)
        {
            // TODO: Use bufferSize argument
            while (!cancellationToken.IsCancellationRequested)
            {
                var result = await input.ReadAsync();

                var inputBuffer = result.Buffer;
                try
                {
                    if (inputBuffer.IsEmpty && result.IsCompleted)
                    {
                        return;
                    }

                    await inputBuffer.CopyToAsync(stream);
                }
                finally
                {
                    input.Advance(inputBuffer.End);
                }
            }
        }
Exemplo n.º 17
0
        protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context)
        {
            long remaining = ContentLength;

            while (remaining > 0)
            {
                var result = await _output.ReadAsync();

                var inputBuffer = result.Buffer;

                var fin = result.IsCompleted;

                var consumed = inputBuffer.Start;

                try
                {
                    if (inputBuffer.IsEmpty && fin)
                    {
                        return;
                    }

                    var data = inputBuffer.Slice(0, remaining);

                    foreach (var memory in data)
                    {
                        await stream.WriteAsync(memory);
                    }

                    consumed   = data.End;
                    remaining -= data.Length;
                }
                finally
                {
                    _output.Advance(consumed);
                }
            }
        }
Exemplo n.º 18
0
        private static async Task <int> ReadAsyncAwaited(this IPipeReader input, ArraySegment <byte> destination)
        {
            while (true)
            {
                var result = await input.ReadAsync();

                var inputBuffer = result.Buffer;

                var length = (int)Math.Min(inputBuffer.Length, destination.Count);
                var sliced = inputBuffer.Slice(0, length);
                sliced.CopyTo(destination);
                input.Advance(sliced.End);

                if (length != 0)
                {
                    return(length);
                }

                if (result.IsCompleted)
                {
                    return(0);
                }
            }
        }
Exemplo n.º 19
0
        public async Task ProcessAllRequests()
        {
            Reset();

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

                var buffer   = result.Buffer;
                var consumed = buffer.Start;
                var examined = buffer.Start;

                try
                {
                    if (buffer.IsEmpty && result.IsCompleted)
                    {
                        // We're done with this connection
                        return;
                    }

                    var parserResult = _parser.ParseRequest(buffer, out consumed, out examined);

                    switch (parserResult)
                    {
                    case HttpRequestParser.ParseResult.Incomplete:
                        if (result.IsCompleted)
                        {
                            // Didn't get the whole request and the connection ended
                            throw new EndOfStreamException();
                        }
                        // Need more data
                        continue;

                    case HttpRequestParser.ParseResult.Complete:
                        // Done
                        break;

                    case HttpRequestParser.ParseResult.BadRequest:
                        // TODO: Don't throw here;
                        throw new Exception();

                    default:
                        break;
                    }
                }
                catch (Exception)
                {
                    StatusCode = 400;

                    await EndResponse();

                    return;
                }
                finally
                {
                    _input.Advance(consumed, examined);
                }

                var context = _application.CreateContext(this);

                try
                {
                    await _application.ProcessRequestAsync(context);
                }
                catch (Exception ex)
                {
                    StatusCode = 500;

                    _application.DisposeContext(context, ex);
                }
                finally
                {
                    await EndResponse();
                }

                if (!KeepAlive)
                {
                    break;
                }

                Reset();
            }
        }
            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();
            }
Exemplo n.º 21
0
 public static void Advance(this IPipeReader input, ReadCursor cursor)
 {
     input.Advance(cursor, cursor);
 }
            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();
            }
Exemplo n.º 23
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);
            }
        }
        internal static async Task <HttpRequest> ParseHttpRequest(IPipeReader input)
        {
            PreservedBuffer Method = default(PreservedBuffer), Path = default(PreservedBuffer), HttpVersion = default(PreservedBuffer);
            Dictionary <string, PreservedBuffer> Headers = new Dictionary <string, PreservedBuffer>();

            try
            {
                ParsingState _state       = ParsingState.StartLine;
                bool         needMoreData = true;
                while (needMoreData)
                {
                    var read = await input.ReadAsync();

                    var buffer = read.Buffer;

                    var consumed = buffer.Start;
                    needMoreData = true;

                    try
                    {
                        if (buffer.IsEmpty && read.IsCompleted)
                        {
                            throw new EndOfStreamException();
                        }

                        if (_state == ParsingState.StartLine)
                        {
                            // Find \n
                            ReadCursor     delim;
                            ReadableBuffer startLine;
                            if (!buffer.TrySliceTo((byte)'\r', (byte)'\n', out startLine, out delim))
                            {
                                continue;
                            }


                            // Move the buffer to the rest
                            buffer = buffer.Slice(delim).Slice(2);

                            ReadableBuffer method;
                            if (!startLine.TrySliceTo((byte)' ', out method, out delim))
                            {
                                throw new Exception();
                            }

                            Method = method.Preserve();

                            // Skip ' '
                            startLine = startLine.Slice(delim).Slice(1);

                            ReadableBuffer path;
                            if (!startLine.TrySliceTo((byte)' ', out path, out delim))
                            {
                                throw new Exception();
                            }

                            Path = path.Preserve();

                            // Skip ' '
                            startLine = startLine.Slice(delim).Slice(1);

                            var httpVersion = startLine;
                            if (httpVersion.IsEmpty)
                            {
                                throw new Exception();
                            }

                            HttpVersion = httpVersion.Preserve();

                            _state   = ParsingState.Headers;
                            consumed = buffer.Start;
                        }

                        // Parse headers
                        // key: value\r\n

                        while (!buffer.IsEmpty)
                        {
                            var ch = Peek(ref buffer);

                            if (ch == -1)
                            {
                                break;
                            }

                            if (ch == '\r')
                            {
                                // Check for final CRLF.
                                buffer = buffer.Slice(1);
                                ch     = Peek(ref buffer);
                                buffer = buffer.Slice(1);

                                if (ch == -1)
                                {
                                    break;
                                }
                                else if (ch == '\n')
                                {
                                    consumed     = buffer.Start;
                                    needMoreData = false;
                                    break;
                                }

                                // Headers don't end in CRLF line.
                                throw new Exception();
                            }

                            var headerName  = default(ReadableBuffer);
                            var headerValue = default(ReadableBuffer);

                            // End of the header
                            // \n
                            ReadCursor     delim;
                            ReadableBuffer headerPair;
                            if (!buffer.TrySliceTo((byte)'\n', out headerPair, out delim))
                            {
                                break;
                            }

                            buffer = buffer.Slice(delim).Slice(1);

                            // :
                            if (!headerPair.TrySliceTo((byte)':', out headerName, out delim))
                            {
                                throw new Exception();
                            }

                            headerName = headerName.TrimStart();
                            headerPair = headerPair.Slice(delim).Slice(1);

                            // \r
                            if (!headerPair.TrySliceTo((byte)'\r', out headerValue, out delim))
                            {
                                // Bad request
                                throw new Exception();
                            }

                            headerValue = headerValue.TrimStart();
                            Headers[ToHeaderKey(ref headerName)] = headerValue.Preserve();

                            // Move the consumed
                            consumed = buffer.Start;
                        }
                    }
                    finally
                    {
                        input.Advance(consumed);
                    }
                }
                var result = new HttpRequest(Method, Path, HttpVersion, Headers);
                Method  = Path = HttpVersion = default(PreservedBuffer);
                Headers = null;
                return(result);
            }
            finally
            {
                Method.Dispose();
                Path.Dispose();
                HttpVersion.Dispose();
                if (Headers != null)
                {
                    foreach (var pair in Headers)
                    {
                        pair.Value.Dispose();
                    }
                }
            }
        }
Exemplo n.º 25
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);
            }
        }
Exemplo n.º 26
0
        public async Task WriteOutputAsync()
        {
            var pool = _thread.WriteReqPool;

            while (true)
            {
                ReadResult result;

                try
                {
                    result = await _pipe.ReadAsync();
                }
                catch
                {
                    // Handled in OnWriterCompleted
                    return;
                }

                var buffer   = result.Buffer;
                var consumed = buffer.End;

                try
                {
                    if (result.IsCancelled)
                    {
                        break;
                    }

                    if (!buffer.IsEmpty)
                    {
                        var writeReq = pool.Allocate();

                        try
                        {
                            if (_socket.IsClosed)
                            {
                                break;
                            }

                            var writeResult = await writeReq.WriteAsync(_socket, buffer);

                            LogWriteInfo(writeResult.Status, writeResult.Error);

                            if (writeResult.Error != null)
                            {
                                consumed = buffer.Start;
                                throw writeResult.Error;
                            }
                        }
                        finally
                        {
                            // Make sure we return the writeReq to the pool
                            pool.Return(writeReq);
                        }
                    }
                    else if (result.IsCompleted)
                    {
                        break;
                    }
                }
                finally
                {
                    _pipe.Advance(consumed);
                }
            }
        }
Exemplo n.º 27
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();
                }
            }