public void ThrowsOnAdvanceWithNoMemory()
 {
     using (var memoryPool = new MemoryPool())
     {
         var pipe      = new ResetablePipe(new PipeOptions(memoryPool));
         var buffer    = pipe.Writer;
         var exception = Assert.Throws <InvalidOperationException>(() => buffer.Advance(1));
         Assert.Equal("No writing operation. Make sure GetMemory() was called.", exception.Message);
     }
 }
 public async Task CanWriteNothingToBuffer()
 {
     using (var memoryPool = new MemoryPool())
     {
         var pipe   = new ResetablePipe(new PipeOptions(memoryPool));
         var buffer = pipe.Writer;
         buffer.GetMemory(0);
         buffer.Advance(0); // doing nothing, the hard way
         await buffer.FlushAsync();
     }
 }
        public static PipeWriter CreateWriter(PipeOptions options, Stream stream)
        {
            if (!stream.CanWrite)
            {
                throw new NotSupportedException();
            }

            var pipe   = new ResetablePipe(options);
            var ignore = pipe.Reader.CopyToEndAsync(stream);

            return(pipe.Writer);
        }
Beispiel #4
0
        public void OnWriterCompletedExceptionSurfacesToReaderScheduler()
        {
            var exception = new Exception();
            var scheduler = new TestScheduler();
            var pipe      = new ResetablePipe(new PipeOptions(_pool, readerScheduler: scheduler));

            pipe.Reader.OnWriterCompleted((e, state) => throw exception, null);
            pipe.Writer.Complete();

            Assert.Equal(1, scheduler.CallCount);
            var aggregateException = Assert.IsType <AggregateException>(scheduler.LastException);

            Assert.Equal(aggregateException.InnerExceptions[0], exception);
        }
Beispiel #5
0
        public void OnWriterCompletedPassesState()
        {
            var callbackRan   = false;
            var callbackState = new object();
            var pipe          = new ResetablePipe(new PipeOptions(_pool));

            pipe.Reader.OnWriterCompleted((exception, state) =>
            {
                Assert.Equal(callbackState, state);
                callbackRan = true;
            }, callbackState);
            pipe.Writer.Complete();

            Assert.True(callbackRan);
        }
        public async Task WriteHex(int value, string hex)
        {
            using (var memoryPool = new MemoryPool())
            {
                var pipe   = new ResetablePipe(new PipeOptions(memoryPool));
                var buffer = pipe.Writer;
                buffer.Append(value, SymbolTable.InvariantUtf8, 'x');
                await buffer.FlushAsync();

                var result = await pipe.Reader.ReadAsync();

                Assert.Equal(hex, result.Buffer.GetAsciiString());
                pipe.Reader.Advance(result.Buffer.End);
            }
        }
Beispiel #7
0
        public void OnWriterCompletedUsingReaderScheduler()
        {
            var callbackRan = false;
            var scheduler   = new TestScheduler();
            var pipe        = new ResetablePipe(new PipeOptions(_pool, readerScheduler: scheduler));

            pipe.Reader.OnWriterCompleted((exception, state) =>
            {
                callbackRan = true;
            }, null);
            pipe.Writer.Complete();

            Assert.True(callbackRan);
            Assert.Equal(1, scheduler.CallCount);
        }
Beispiel #8
0
        public async Task MultipleCompleteReaderWriterCauseDisposeOnlyOnce()
        {
            var pool = new DisposeTrackingBufferPool();

            var readerWriter = new ResetablePipe(new PipeOptions(pool));
            await readerWriter.Writer.WriteAsync(new byte[] { 1 });

            readerWriter.Writer.Complete();
            readerWriter.Reader.Complete();
            Assert.Equal(1, pool.ReturnedBlocks);

            readerWriter.Writer.Complete();
            readerWriter.Reader.Complete();
            Assert.Equal(1, pool.ReturnedBlocks);
        }
Beispiel #9
0
        public void OnReaderCompletedPassesException()
        {
            var callbackRan     = false;
            var pipe            = new ResetablePipe(new PipeOptions(_pool));
            var readerException = new Exception();

            pipe.Writer.OnReaderCompleted((exception, state) =>
            {
                callbackRan = true;
                Assert.Same(readerException, exception);
            }, null);
            pipe.Reader.Complete(readerException);

            Assert.True(callbackRan);
        }
        public async Task CanWriteUInt64ToBuffer(ulong value, string valueAsString)
        {
            using (var memoryPool = new MemoryPool())
            {
                var pipe   = new ResetablePipe(new PipeOptions(memoryPool));
                var buffer = pipe.Writer;
                buffer.Append(value, SymbolTable.InvariantUtf8);
                await buffer.FlushAsync();

                var result = await pipe.Reader.ReadAsync();

                var inputBuffer = result.Buffer;

                Assert.Equal(valueAsString, inputBuffer.GetUtf8Span());
            }
        }
Beispiel #11
0
        public async Task WriteDuringReadIsNotReturned()
        {
            var pool = new DisposeTrackingBufferPool();

            var writeSize = 512;

            var pipe = new ResetablePipe(new PipeOptions(pool));
            await pipe.Writer.WriteAsync(new byte[writeSize]);

            pipe.Writer.GetMemory(writeSize);
            var readResult = await pipe.Reader.ReadAsync();

            pipe.Reader.Advance(readResult.Buffer.End);
            pipe.Writer.Write(new byte[writeSize]);
            pipe.Writer.Commit();

            Assert.Equal(1, pool.CurrentlyRentedBlocks);
        }
Beispiel #12
0
        public void CompletingWriterFromReaderCallbackWorks()
        {
            var callbackRan = false;
            var pipe        = new ResetablePipe(new PipeOptions(_pool, maximumSizeHigh: 5));

            pipe.Reader.OnWriterCompleted((exception, state) =>
            {
                pipe.Reader.Complete();
            }, null);

            pipe.Writer.OnReaderCompleted((exception, state) =>
            {
                callbackRan = true;
            }, null);

            pipe.Writer.Complete();
            Assert.True(callbackRan);
        }
Beispiel #13
0
        internal SocketConnection(Socket socket, MemoryPool <byte> pool)
        {
            socket.NoDelay = true;
            _socket        = socket;
            if (pool == null)
            {
                _ownsPool = true;
                pool      = new MemoryPool();
            }
            _pool = pool;

            // TODO: Make this configurable
            // Dispatch to avoid deadlocks
            _input  = new ResetablePipe(new PipeOptions(pool, Scheduler.ThreadPool, Scheduler.ThreadPool));
            _output = new ResetablePipe(new PipeOptions(pool, Scheduler.ThreadPool, Scheduler.ThreadPool));

            _receiveTask = ReceiveFromSocketAndPushToWriterAsync();
            _sendTask    = ReadFromReaderAndWriteToSocketAsync();
        }
Beispiel #14
0
        public async Task AdvanceToEndReturnsAllBlocks()
        {
            var pool = new DisposeTrackingBufferPool();

            var writeSize = 512;

            var pipe = new ResetablePipe(new PipeOptions(pool));

            while (pool.CurrentlyRentedBlocks != 3)
            {
                var writableBuffer = pipe.Writer.WriteEmpty(writeSize);
                await writableBuffer.FlushAsync();
            }

            var readResult = await pipe.Reader.ReadAsync();

            pipe.Reader.Advance(readResult.Buffer.End);

            Assert.Equal(0, pool.CurrentlyRentedBlocks);
        }
Beispiel #15
0
        public async Task FlushCallbackRunsOnWriterScheduler()
        {
            using (var pool = new MemoryPool())
            {
                using (var scheduler = new ThreadScheduler())
                {
                    var pipe = new ResetablePipe(new PipeOptions(pool,
                                                                 maximumSizeLow: 32,
                                                                 maximumSizeHigh: 64,
                                                                 writerScheduler: scheduler));

                    var writableBuffer = pipe.Writer.WriteEmpty(64);
                    var flushAsync     = writableBuffer.FlushAsync();

                    Assert.False(flushAsync.IsCompleted);

                    Func <Task> doWrite = async() =>
                    {
                        var oid = Thread.CurrentThread.ManagedThreadId;

                        await flushAsync;

                        Assert.NotEqual(oid, Thread.CurrentThread.ManagedThreadId);

                        pipe.Writer.Complete();

                        Assert.Equal(Thread.CurrentThread.ManagedThreadId, scheduler.Thread.ManagedThreadId);
                    };

                    var writing = doWrite();

                    var result = await pipe.Reader.ReadAsync();

                    pipe.Reader.Advance(result.Buffer.End, result.Buffer.End);

                    pipe.Reader.Complete();

                    await writing;
                }
            }
        }
Beispiel #16
0
        public async Task RentsMinimumSegmentSize()
        {
            var pool      = new DisposeTrackingBufferPool();
            var writeSize = 512;

            var pipe = new ResetablePipe(new PipeOptions(pool, minimumSegmentSize: 2020));

            var buffer        = pipe.Writer.GetMemory(writeSize);
            var allocatedSize = buffer.Length;

            pipe.Writer.Advance(buffer.Length);
            buffer = pipe.Writer.GetMemory(1);
            var ensuredSize = buffer.Length;
            await pipe.Writer.FlushAsync();

            pipe.Reader.Complete();
            pipe.Writer.Complete();

            Assert.Equal(2020, ensuredSize);
            Assert.Equal(2020, allocatedSize);
        }
Beispiel #17
0
        public async Task CopyToAsync()
        {
            using (var pool = new MemoryPool())
            {
                var readerWriter = new ResetablePipe(new PipeOptions(pool));
                var output       = readerWriter.Writer;
                output.Append("Hello World", SymbolTable.InvariantUtf8);
                await output.FlushAsync();

                var ms     = new MemoryStream();
                var result = await readerWriter.Reader.ReadAsync();

                var rb = result.Buffer;
                await rb.CopyToAsync(ms);

                ms.Position = 0;
                Assert.Equal(11, rb.Length);
                Assert.Equal(11, ms.Length);
                Assert.Equal(rb.ToArray(), ms.ToArray());
                Assert.Equal("Hello World", Encoding.ASCII.GetString(ms.ToArray()));
            }
        }
Beispiel #18
0
        public async Task DefaultWriterSchedulerRunsInline()
        {
            using (var pool = new MemoryPool())
            {
                var pipe = new ResetablePipe(new PipeOptions(pool,
                                                             maximumSizeLow: 32,
                                                             maximumSizeHigh: 64
                                                             ));

                var writableBuffer = pipe.Writer.WriteEmpty(64);
                var flushAsync     = writableBuffer.FlushAsync();

                Assert.False(flushAsync.IsCompleted);

                int id = 0;

                Func <Task> doWrite = async() =>
                {
                    await flushAsync;

                    pipe.Writer.Complete();

                    Assert.Equal(Thread.CurrentThread.ManagedThreadId, id);
                };

                var writing = doWrite();

                var result = await pipe.Reader.ReadAsync();

                id = Thread.CurrentThread.ManagedThreadId;

                pipe.Reader.Advance(result.Buffer.End, result.Buffer.End);

                pipe.Reader.Complete();

                await writing;
            }
        }
Beispiel #19
0
        public void OnWriterCompletedRanBeforeReadContinuation()
        {
            var callbackRan     = false;
            var continuationRan = false;
            var pipe            = new ResetablePipe(new PipeOptions(_pool));

            pipe.Reader.OnWriterCompleted((exception, state) =>
            {
                callbackRan = true;
                Assert.False(continuationRan);
            }, null);

            var awaiter = pipe.Reader.ReadAsync();

            Assert.False(awaiter.IsCompleted);
            awaiter.OnCompleted(() =>
            {
                continuationRan = true;
            });
            pipe.Writer.Complete();

            Assert.True(callbackRan);
        }
        public async Task WriteLargeDataTextAscii(int length)
        {
            string data = new string('#', length);

            FillRandomStringData(data, length);
            using (var memoryPool = new MemoryPool())
            {
                var pipe = new ResetablePipe(new PipeOptions(memoryPool));

                var output = pipe.Writer;
                output.Append(data, SymbolTable.InvariantUtf8);
                var foo = output.GetMemory().IsEmpty; // trying to see if .Memory breaks
                await output.FlushAsync();

                pipe.Writer.Complete();

                long offset = 0;
                while (true)
                {
                    var result = await pipe.Reader.ReadAsync();

                    var input = result.Buffer;
                    if (input.Length == 0)
                    {
                        break;
                    }

                    string s = ReadableBufferExtensions.GetAsciiString(input);
                    // We are able to cast because test arguments are in range of int
                    Assert.Equal(data.Substring((int)offset, (int)input.Length), s);
                    offset += input.Length;
                    pipe.Reader.Advance(input.End);
                }
                Assert.Equal(data.Length, offset);
            }
        }
 public WritableBufferWriterFacts()
 {
     _pool = new MemoryPool();
     _pipe = new ResetablePipe(new PipeOptions(_pool));
 }
Beispiel #22
0
        public void OnWriterCompletedThrowsWithNullCallback()
        {
            var pipe = new ResetablePipe(new PipeOptions(_pool));

            Assert.Throws <ArgumentNullException>(() => pipe.Reader.OnWriterCompleted(null, null));
        }
Beispiel #23
0
 public PipeConnection(PipeOptions pipeOptions)
 {
     Input  = new ResetablePipe(pipeOptions);
     Output = new ResetablePipe(pipeOptions);
 }
Beispiel #24
0
 public PipeResetTests()
 {
     _pool = new MemoryPool();
     _pipe = new ResetablePipe(new PipeOptions(_pool));
 }
Beispiel #25
0
 public BackpressureTests()
 {
     _pool = new MemoryPool();
     _pipe = new ResetablePipe(new PipeOptions(_pool, maximumSizeLow: 32, maximumSizeHigh: 64));
 }