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); } }
public Task ReadInputAsync() { _block = _memory.Lease(); // Use pooled block for copy return(FilterInputAsync(_block).ContinueWith((task, state) => { ((FilteredStreamAdapter)state).OnStreamClose(task); }, this)); }
public void Internationalized(string raw, string expect) { using (var pool = new MemoryPool()) { var mem = pool.Lease(); PositiveAssert(mem, raw, expect); pool.Return(mem); } }
public void Empty() { using (var pool = new MemoryPool()) { var mem = pool.Lease(); PositiveAssert(mem, string.Empty, string.Empty); pool.Return(mem); } }
public void ValidUTF8(string raw, string expect) { using (var pool = new MemoryPool()) { var mem = pool.Lease(); PositiveAssert(mem, raw, expect); pool.Return(mem); } }
public void SkipForwardSlash(string raw, string expect) { using (var pool = new MemoryPool()) { var mem = pool.Lease(); PositiveAssert(mem, raw, expect); pool.Return(mem); } }
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); } }
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); } }
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); } }
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; }
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; }