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(); } }
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); } }
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; }
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); } }
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(); } }
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(); }