public void IsEndCorrectlyTraversesBlocks()
        {
            using (var pool = new MemoryPool())
            {
                var block1 = pool.Lease(128);
                var block2 = block1.Next = pool.Lease(128);
                var block3 = block2.Next = pool.Lease(128);
                var block4 = block3.Next = pool.Lease(128);

                // There is no data in block2 or block4, so IsEnd should be true after 256 bytes are read.
                block1.End += 128;
                block3.End += 128;

                var iterStart = block1.GetIterator();
                var iterMid   = iterStart.Add(128);
                var iterEnd   = iterMid.Add(128);

                Assert.False(iterStart.IsEnd);
                Assert.False(iterMid.IsEnd);
                Assert.True(iterEnd.IsEnd);

                pool.Return(block1);
                pool.Return(block2);
                pool.Return(block3);
                pool.Return(block4);
            }
        }
        public void GetLengthBetweenIteratorsWorks()
        {
            using (var pool = new MemoryPool())
            {
                var block = pool.Lease(256);
                block.End += 256;
                TestAllLengths(block, 256);
                pool.Return(block);
                block = null;

                for (var fragment = 0; fragment < 256; fragment += 4)
                {
                    var next = block;
                    block      = pool.Lease(4);
                    block.Next = next;
                    block.End += 4;
                }

                TestAllLengths(block, 256);

                while (block != null)
                {
                    var next = block.Next;
                    pool.Return(block);
                    block = next;
                }
            }
        }
        public void SeekWorksAcrossBlocks()
        {
            using (var pool = new MemoryPool())
            {
                var block1 = pool.Lease();
                var block2 = block1.Next = pool.Lease();
                var block3 = block2.Next = pool.Lease();

                foreach (var ch in Enumerable.Range(0, 34).Select(x => (byte)x))
                {
                    block1.Array[block1.End++] = ch;
                }
                foreach (var ch in Enumerable.Range(34, 25).Select(x => (byte)x))
                {
                    block2.Array[block2.End++] = ch;
                }
                foreach (var ch in Enumerable.Range(59, 197).Select(x => (byte)x))
                {
                    block3.Array[block3.End++] = ch;
                }

                var vectorMaxValues = new Vector <byte>(byte.MaxValue);

                var iterator = block1.GetIterator();
                foreach (var ch in Enumerable.Range(0, 256).Select(x => (byte)x))
                {
                    var vectorCh = new Vector <byte>(ch);

                    var hit = iterator;
                    hit.Seek(ref vectorCh);
                    Assert.Equal(ch, iterator.GetLength(hit));

                    hit = iterator;
                    hit.Seek(ref vectorCh, ref vectorMaxValues);
                    Assert.Equal(ch, iterator.GetLength(hit));

                    hit = iterator;
                    hit.Seek(ref vectorMaxValues, ref vectorCh);
                    Assert.Equal(ch, iterator.GetLength(hit));

                    hit = iterator;
                    hit.Seek(ref vectorCh, ref vectorMaxValues, ref vectorMaxValues);
                    Assert.Equal(ch, iterator.GetLength(hit));

                    hit = iterator;
                    hit.Seek(ref vectorMaxValues, ref vectorCh, ref vectorMaxValues);
                    Assert.Equal(ch, iterator.GetLength(hit));

                    hit = iterator;
                    hit.Seek(ref vectorMaxValues, ref vectorMaxValues, ref vectorCh);
                    Assert.Equal(ch, iterator.GetLength(hit));
                }

                pool.Return(block1);
                pool.Return(block2);
                pool.Return(block3);
            }
        }
        public MemoryPoolBlock IncomingStart()
        {
            const int minimumSize = 2048;

            if (_tail != null && minimumSize <= _tail.Data.Offset + _tail.Data.Count - _tail.End)
            {
                _pinned = _tail;
            }
            else
            {
                _pinned = _memory.Lease();
            }

            return(_pinned);
        }
        private void FullAsciiRangeSupported()
        {
            var byteRange = Enumerable.Range(1, 127).Select(x => (byte)x).ToArray();

            using (var pool = new MemoryPool())
            {
                var mem = pool.Lease();
                mem.GetIterator().CopyFrom(byteRange);

                var begin = mem.GetIterator();
                var end   = GetIterator(begin, byteRange.Length);

                var s = begin.GetAsciiString(end);

                Assert.Equal(s.Length, byteRange.Length);

                for (var i = 1; i < byteRange.Length; i++)
                {
                    var sb = (byte)s[i];
                    var b  = byteRange[i];

                    Assert.Equal(sb, b);
                }

                pool.Return(mem);
            }
        }
        private void LargeAllocationProducesCorrectResults()
        {
            var byteRange         = Enumerable.Range(0, 16384 + 64).Select(x => (byte)((x & 0x7f) | 0x01)).ToArray();
            var expectedByteRange = byteRange.Concat(byteRange).ToArray();

            using (var pool = new MemoryPool())
            {
                var mem0 = pool.Lease();
                var mem1 = pool.Lease();
                mem0.GetIterator().CopyFrom(byteRange);
                mem1.GetIterator().CopyFrom(byteRange);

                var lastBlock = mem0;
                while (lastBlock.Next != null)
                {
                    lastBlock = lastBlock.Next;
                }
                lastBlock.Next = mem1;

                var begin = mem0.GetIterator();
                var end   = GetIterator(begin, expectedByteRange.Length);

                var s = begin.GetAsciiString(end);

                Assert.Equal(expectedByteRange.Length, s.Length);

                for (var i = 0; i < expectedByteRange.Length; i++)
                {
                    var sb = (byte)((s[i] & 0x7f) | 0x01);
                    var b  = expectedByteRange[i];

                    Assert.Equal(sb, b);
                }

                var block = mem0;
                while (block != null)
                {
                    var returnBlock = block;
                    block = block.Next;
                    pool.Return(returnBlock);
                }

                pool.Return(mem0);
                pool.Return(mem1);
            }
        }
        private void MultiBlockProducesCorrectResults()
        {
            var byteRange         = Enumerable.Range(0, 512 + 64).Select(x => (byte)((x & 0x7f) | 0x01)).ToArray();
            var expectedByteRange = byteRange
                                    .Concat(byteRange)
                                    .Concat(byteRange)
                                    .Concat(byteRange)
                                    .ToArray();

            using (var pool = new MemoryPool())
            {
                var mem0 = pool.Lease();
                var mem1 = pool.Lease();
                var mem2 = pool.Lease();
                var mem3 = pool.Lease();
                mem0.GetIterator().CopyFrom(byteRange);
                mem1.GetIterator().CopyFrom(byteRange);
                mem2.GetIterator().CopyFrom(byteRange);
                mem3.GetIterator().CopyFrom(byteRange);

                mem0.Next = mem1;
                mem1.Next = mem2;
                mem2.Next = mem3;

                var begin = mem0.GetIterator();
                var end   = GetIterator(begin, expectedByteRange.Length);

                var s = begin.GetAsciiString(end);

                Assert.Equal(s.Length, expectedByteRange.Length);

                for (var i = 0; i < expectedByteRange.Length; i++)
                {
                    var sb = (byte)((s[i] & 0x7f) | 0x01);
                    var b  = expectedByteRange[i];

                    Assert.Equal(sb, b);
                }

                pool.Return(mem0);
                pool.Return(mem1);
                pool.Return(mem2);
                pool.Return(mem3);
            }
        }
Example #8
0
 public Task ReadInputAsync()
 {
     _block = _memory.Lease();
     // Use pooled block for copy
     return(FilterInputAsync(_block).ContinueWith((task, state) =>
     {
         ((FilteredStreamAdapter)state).OnStreamClose(task);
     }, this));
 }
Example #9
0
        public void Internationalized(string raw, string expect)
        {
            using (var pool = new MemoryPool())
            {
                var mem = pool.Lease();

                PositiveAssert(mem, raw, expect);

                pool.Return(mem);
            }
        }
Example #10
0
        public void Empty()
        {
            using (var pool = new MemoryPool())
            {
                var mem = pool.Lease();

                PositiveAssert(mem, string.Empty, string.Empty);

                pool.Return(mem);
            }
        }
Example #11
0
        public void ValidUTF8(string raw, string expect)
        {
            using (var pool = new MemoryPool())
            {
                var mem = pool.Lease();

                PositiveAssert(mem, raw, expect);

                pool.Return(mem);
            }
        }
Example #12
0
        public void SkipForwardSlash(string raw, string expect)
        {
            using (var pool = new MemoryPool())
            {
                var mem = pool.Lease();

                PositiveAssert(mem, raw, expect);

                pool.Return(mem);
            }
        }
Example #13
0
        public void WhiteSpace()
        {
            using (var pool = new MemoryPool())
            {
                var mem = pool.Lease();

                PositiveAssert(mem, "    ", "    ");

                pool.Return(mem);
            }
        }
        public static void Setup()
        {
            if (Pool == null)
            {
                Pool = new MemoryPool();
                Pool.Lease(1024).Dispose();
            }

            if (ChannelFactory == null)
            {
                ChannelFactory = new ChannelFactory(Pool);
            }
        }
        public void AddDoesNotAdvanceAtEndOfCurrentBlock()
        {
            using (var pool = new MemoryPool())
            {
                var block1 = pool.Lease(256);
                var block2 = block1.Next = pool.Lease(256);

                block1.End += 100;
                block2.End += 200;

                var iter0   = block1.GetIterator();
                var iter100 = iter0.Add(100);

                var iter200a = iter0.Add(200);
                var iter200b = iter100.Add(100);

                var iter300a = iter0.Add(300);
                var iter300b = iter100.Add(200);
                var iter300c = iter200a.Add(100);

                var iter300a2 = iter300a.Add(1);
                var iter300b2 = iter300b.Add(1);
                var iter300c2 = iter300c.Add(1);

                AssertIterator(iter0, block1, block1.Start);
                AssertIterator(iter100, block1, block1.End);
                AssertIterator(iter200a, block2, block2.Start + 100);
                AssertIterator(iter200b, block2, block2.Start + 100);
                AssertIterator(iter300a, block2, block2.End);
                AssertIterator(iter300b, block2, block2.End);
                AssertIterator(iter300c, block2, block2.End);
                AssertIterator(iter300a2, block2, block2.End);
                AssertIterator(iter300b2, block2, block2.End);
                AssertIterator(iter300c2, block2, block2.End);

                pool.Return(block1);
                pool.Return(block2);
            }
        }
Example #16
0
        public void ProducingStartAndProducingCompleteCanBeUsedDirectly()
        {
            int nBuffers  = 0;
            var nBufferWh = new ManualResetEventSlim();

            var mockLibuv = new MockLibuv
            {
                OnWrite = (socket, buffers, triggerCompleted) =>
                {
                    nBuffers = buffers;
                    nBufferWh.Set();
                    triggerCompleted(0);
                    return(0);
                }
            };

            using (var memory = new MemoryPool())
                using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext()))
                {
                    kestrelEngine.Start(count: 1);

                    var kestrelThread = kestrelEngine.Threads[0];
                    var socket        = new MockSocket(mockLibuv, kestrelThread.Loop.ThreadId, new TestKestrelTrace());
                    var trace         = new KestrelTrace(new TestKestrelTrace());
                    var ltp           = new LoggingThreadPool(trace);
                    var socketOutput  = new SocketOutput(kestrelThread, socket, memory, new MockConnection(), "0", trace, ltp, new Queue <UvWriteReq>());

                    // block 1
                    var start = socketOutput.ProducingStart();
                    start.Block.End = start.Block.Data.Offset + start.Block.Data.Count;

                    // block 2
                    var block2 = memory.Lease();
                    block2.End       = block2.Data.Offset + block2.Data.Count;
                    start.Block.Next = block2;

                    var end = new MemoryPoolIterator(block2, block2.End);

                    socketOutput.ProducingComplete(end);

                    // A call to Write is required to ensure a write is scheduled
                    socketOutput.WriteAsync(default(ArraySegment <byte>), default(CancellationToken));

                    Assert.True(nBufferWh.Wait(1000));
                    Assert.Equal(2, nBuffers);

                    // Cleanup
                    var cleanupTask = socketOutput.WriteAsync(
                        default(ArraySegment <byte>), default(CancellationToken), socketDisconnect: true);
                }
        }
        public void CopyToCorrectlyTraversesBlocks()
        {
            using (var pool = new MemoryPool())
            {
                var block1 = pool.Lease(128);
                var block2 = block1.Next = pool.Lease(128);

                for (int i = 0; i < 128; i++)
                {
                    block1.Array[block1.End++] = (byte)i;
                }
                for (int i = 128; i < 256; i++)
                {
                    block2.Array[block2.End++] = (byte)i;
                }

                var beginIterator = block1.GetIterator();

                var array = new byte[256];
                int actual;
                var endIterator = beginIterator.CopyTo(array, 0, 256, out actual);

                Assert.Equal(256, actual);

                for (int i = 0; i < 256; i++)
                {
                    Assert.Equal(i, array[i]);
                }

                endIterator.CopyTo(array, 0, 256, out actual);
                Assert.Equal(0, actual);

                pool.Return(block1);
                pool.Return(block2);
            }
        }
Example #18
0
        public void MemorySeek(string raw, string search, char expectResult, int expectIndex)
        {
            var block = _pool.Lease(256);
            var chars = raw.ToCharArray().Select(c => (byte)c).ToArray();

            Buffer.BlockCopy(chars, 0, block.Array, block.Start, chars.Length);
            block.End += chars.Length;

            var begin     = block.GetIterator();
            var searchFor = search.ToCharArray();

            int found = -1;

            if (searchFor.Length == 1)
            {
                var search0 = new Vector <byte>((byte)searchFor[0]);
                found = begin.Seek(ref search0);
            }
            else if (searchFor.Length == 2)
            {
                var search0 = new Vector <byte>((byte)searchFor[0]);
                var search1 = new Vector <byte>((byte)searchFor[1]);
                found = begin.Seek(ref search0, ref search1);
            }
            else if (searchFor.Length == 3)
            {
                var search0 = new Vector <byte>((byte)searchFor[0]);
                var search1 = new Vector <byte>((byte)searchFor[1]);
                var search2 = new Vector <byte>((byte)searchFor[2]);
                found = begin.Seek(ref search0, ref search1, ref search2);
            }
            else
            {
                Assert.False(true, "Invalid test sample.");
            }

            Assert.Equal(expectResult, found);
            Assert.Equal(expectIndex, begin.Index - block.Start);

            _pool.Return(block);
        }
        public void SeekWorks()
        {
            using (var pool = new MemoryPool())
            {
                var block = pool.Lease(256);
                foreach (var ch in Enumerable.Range(0, 256).Select(x => (byte)x))
                {
                    block.Array[block.End++] = ch;
                }

                var vectorMaxValues = new Vector <byte>(byte.MaxValue);

                var iterator = block.GetIterator();
                foreach (var ch in Enumerable.Range(0, 256).Select(x => (byte)x))
                {
                    var vectorCh = new Vector <byte>(ch);

                    var hit = iterator;
                    hit.Seek(ref vectorCh);
                    Assert.Equal(ch, iterator.GetLength(hit));

                    hit = iterator;
                    hit.Seek(ref vectorCh, ref vectorMaxValues);
                    Assert.Equal(ch, iterator.GetLength(hit));

                    hit = iterator;
                    hit.Seek(ref vectorMaxValues, ref vectorCh);
                    Assert.Equal(ch, iterator.GetLength(hit));

                    hit = iterator;
                    hit.Seek(ref vectorCh, ref vectorMaxValues, ref vectorMaxValues);
                    Assert.Equal(ch, iterator.GetLength(hit));

                    hit = iterator;
                    hit.Seek(ref vectorMaxValues, ref vectorCh, ref vectorMaxValues);
                    Assert.Equal(ch, iterator.GetLength(hit));

                    hit = iterator;
                    hit.Seek(ref vectorCh, ref vectorMaxValues, ref vectorMaxValues);
                    Assert.Equal(ch, iterator.GetLength(hit));
                }

                pool.Return(block);
            }
        }
Example #20
0
        public void DecodeWithBoundary(string raw, int rawLength, string expect, int expectLength)
        {
            using (var pool = new MemoryPool())
            {
                var mem = pool.Lease();

                var begin = BuildSample(mem, raw);
                var end   = GetIterator(begin, rawLength);

                var end2   = UrlPathDecoder.Unescape(begin, end);
                var result = begin.GetUtf8String(end2);

                Assert.Equal(expectLength, result.Length);
                Assert.Equal(expect, result);

                pool.Return(mem);
            }
        }
        public void CopyFromCorrectlyTraversesBlocks()
        {
            using (var pool = new MemoryPool())
            {
                var block1     = pool.Lease(128);
                var start      = block1.GetIterator();
                var end        = start;
                var bufferSize = block1.Data.Count * 3;
                var buffer     = new byte[bufferSize];

                for (int i = 0; i < bufferSize; i++)
                {
                    buffer[i] = (byte)(i % 73);
                }

                Assert.Null(block1.Next);

                end.CopyFrom(new ArraySegment <byte>(buffer));

                Assert.NotNull(block1.Next);

                for (int i = 0; i < bufferSize; i++)
                {
                    Assert.Equal(i % 73, start.Take());
                }

                Assert.Equal(-1, start.Take());
                Assert.Equal(start.Block, end.Block);
                Assert.Equal(start.Index, end.Index);

                var block = block1;
                while (block != null)
                {
                    var returnBlock = block;
                    block = block.Next;

                    pool.Return(returnBlock);
                }
            }
        }
        private void ExceptionThrownForZeroOrNonAscii(byte b)
        {
            for (var length = 1; length < 16; length++)
            {
                for (var position = 0; position < length; position++)
                {
                    var byteRange = Enumerable.Range(1, length).Select(x => (byte)x).ToArray();
                    byteRange[position] = b;

                    using (var pool = new MemoryPool())
                    {
                        var mem = pool.Lease();
                        mem.GetIterator().CopyFrom(byteRange);

                        var begin = mem.GetIterator();
                        var end   = GetIterator(begin, byteRange.Length);

                        Assert.Throws <BadHttpRequestException>(() => begin.GetAsciiString(end));
                    }
                }
            }
        }
        public SocketOutput(
            KestrelThread thread,
            UvStreamHandle socket,
            MemoryPool memory,
            Connection connection,
            string connectionId,
            IKestrelTrace log,
            IThreadPool threadPool,
            Queue <UvWriteReq> writeReqPool)
        {
            _thread           = thread;
            _socket           = socket;
            _connection       = connection;
            _connectionId     = connectionId;
            _log              = log;
            _threadPool       = threadPool;
            _tasksPending     = new Queue <WaitingTask>(_initialTaskQueues);
            _writeContextPool = new Queue <WriteContext>(_maxPooledWriteContexts);
            _writeReqPool     = writeReqPool;

            _head = memory.Lease();
            _tail = _head;
        }
Example #24
0
        public void ServerPipeListenForConnections()
        {
            const string pipeName = @"\\.\pipe\ServerPipeListenForConnections";

            var loop             = new UvLoopHandle(_logger);
            var serverListenPipe = new UvPipeHandle(_logger);

            loop.Init(_uv);
            serverListenPipe.Init(loop, (a, b) => { }, false);
            serverListenPipe.Bind(pipeName);
            serverListenPipe.Listen(128, (backlog, status, error, state) =>
            {
                var serverConnectionPipe = new UvPipeHandle(_logger);
                serverConnectionPipe.Init(loop, (a, b) => { }, true);

                try
                {
                    serverListenPipe.Accept(serverConnectionPipe);
                }
                catch (Exception)
                {
                    serverConnectionPipe.Dispose();
                    return;
                }

                var writeRequest = new UvWriteReq(new KestrelTrace(new TestKestrelTrace()));
                writeRequest.Init(loop);

                var pool  = new MemoryPool();
                var block = pool.Lease();
                block.GetIterator().CopyFrom(new ArraySegment <byte>(new byte[] { 1, 2, 3, 4 }));

                var start = new MemoryPoolIterator(block, 0);
                var end   = new MemoryPoolIterator(block, block.Data.Count);
                writeRequest.Write(
                    serverConnectionPipe,
                    start,
                    end,
                    1,
                    (handle, status2, error2, state2) =>
                {
                    writeRequest.Dispose();
                    serverConnectionPipe.Dispose();
                    serverListenPipe.Dispose();
                    pool.Return(block);
                    pool.Dispose();
                },
                    null);
            }, null);

            var worker = new Thread(() =>
            {
                var loop2 = new UvLoopHandle(_logger);
                var clientConnectionPipe = new UvPipeHandle(_logger);
                var connect = new UvConnectRequest(new KestrelTrace(new TestKestrelTrace()));

                loop2.Init(_uv);
                clientConnectionPipe.Init(loop2, (a, b) => { }, true);
                connect.Init(loop2);
                connect.Connect(clientConnectionPipe, pipeName, (handle, status, error, state) =>
                {
                    var buf = loop2.Libuv.buf_init(Marshal.AllocHGlobal(8192), 8192);
                    connect.Dispose();

                    clientConnectionPipe.ReadStart(
                        (handle2, cb, state2) => buf,
                        (handle2, status2, state2) =>
                    {
                        if (status2 == Constants.EOF)
                        {
                            clientConnectionPipe.Dispose();
                        }
                    },
                        null);
                }, null);
                loop2.Run();
                loop2.Dispose();
            });

            worker.Start();
            loop.Run();
            loop.Dispose();
            worker.Join();
        }
 public MemoryPoolIterator ProducingStart()
 {
     _producingBlock = _memory.Lease();
     return(new MemoryPoolIterator(_producingBlock));
 }
        public async Task SocketCanReadAndWrite()
        {
            var loop = new UvLoopHandle(_logger);

            loop.Init(_uv);
            var tcp = new UvTcpHandle(_logger);

            tcp.Init(loop, (a, b) => { });
            var address = ServerAddress.FromUrl($"http://127.0.0.1:0/");

            tcp.Bind(address);
            var port = tcp.GetSockIPEndPoint().Port;

            tcp.Listen(10, (_, status, error, state) =>
            {
                var tcp2 = new UvTcpHandle(_logger);
                tcp2.Init(loop, (a, b) => { });
                tcp.Accept(tcp2);
                var data = Marshal.AllocCoTaskMem(500);
                tcp2.ReadStart(
                    (a, b, c) => tcp2.Libuv.buf_init(data, 500),
                    (__, nread, state2) =>
                {
                    if (nread <= 0)
                    {
                        tcp2.Dispose();
                    }
                    else
                    {
                        for (var x = 0; x < 2; x++)
                        {
                            var req = new UvWriteReq(new KestrelTrace(new TestKestrelTrace()));
                            req.Init(loop); var pool = new MemoryPool();
                            var block = pool.Lease();
                            block.GetIterator().CopyFrom(new ArraySegment <byte>(new byte[] { 65, 66, 67, 68, 69 }));

                            var start = new MemoryPoolIterator(block, 0);
                            var end   = new MemoryPoolIterator(block, block.Data.Count);
                            req.Write(
                                tcp2,
                                start,
                                end,
                                1,
                                (_1, _2, _3, _4) =>
                            {
                                pool.Return(block);
                                pool.Dispose();
                            },
                                null);
                        }
                    }
                },
                    null);
                tcp.Dispose();
            }, null);
            var t = Task.Run(async() =>
            {
                var socket = TestConnection.CreateConnectedLoopbackSocket(port);
#if NET451
                await Task.Factory.FromAsync(
                    socket.BeginSend,
                    socket.EndSend,
                    new[] { new ArraySegment <byte>(new byte[] { 1, 2, 3, 4, 5 }) },
                    SocketFlags.None,
                    null,
                    TaskCreationOptions.None);
#else
                await socket.SendAsync(new[] { new ArraySegment <byte>(new byte[] { 1, 2, 3, 4, 5 }) },
                                       SocketFlags.None);
#endif
                socket.Shutdown(SocketShutdown.Send);
                var buffer = new ArraySegment <byte>(new byte[2048]);
                while (true)
                {
#if NET451
                    var count = await Task.Factory.FromAsync(
                        socket.BeginReceive,
                        socket.EndReceive,
                        new[] { buffer },
                        SocketFlags.None,
                        null,
                        TaskCreationOptions.None);
#else
                    var count = await socket.ReceiveAsync(new[] { buffer }, SocketFlags.None);
#endif
                    if (count <= 0)
                    {
                        break;
                    }
                }
                socket.Dispose();
            });

            loop.Run();
            loop.Dispose();
            await t;
        }