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 void MemoryPoolBlockReferenceTests()
        {
            var pool = new MemoryPool();

            BufferReferenceTests.TestOwnedBuffer(() => pool.Rent(1024), block => pool.Return((MemoryPoolBlock)block));
            pool.Dispose();
        }
예제 #5
0
        private void OnStreamClose(Task copyAsyncTask)
        {
            _memory.Return(_block);

            if (copyAsyncTask.IsFaulted)
            {
                SocketInput.AbortAwaiting();
                Service.Logger.Log(copyAsyncTask.Exception);
            }
            else if (copyAsyncTask.IsCanceled)
            {
                SocketInput.AbortAwaiting();
                Service.Logger.Log(LogLevel.Error, "FilteredStreamAdapter.CopyToAsync canceled.");
            }
            else if (_aborted)
            {
                SocketInput.AbortAwaiting();
            }

            try
            {
                SocketInput.IncomingFin();
            }
            catch (Exception ex)
            {
                Service.Logger.Log(ex);
            }
        }
예제 #6
0
        private void OnStreamClose(Task copyAsyncTask)
        {
            _memory.Return(_block);

            if (copyAsyncTask.IsFaulted)
            {
                SocketInput.AbortAwaiting();
                _log.LogError(0, copyAsyncTask.Exception, "FilteredStreamAdapter.CopyToAsync");
            }
            else if (copyAsyncTask.IsCanceled)
            {
                SocketInput.AbortAwaiting();
                _log.LogError("FilteredStreamAdapter.CopyToAsync canceled.");
            }
            else if (_aborted)
            {
                SocketInput.AbortAwaiting();
            }

            try
            {
                _socketInputStream.Dispose();
            }
            catch (Exception ex)
            {
                _log.LogError(0, ex, "FilteredStreamAdapter.OnStreamClose");
            }
        }
        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);
            }
        }
예제 #10
0
        public void Empty()
        {
            using (var pool = new MemoryPool())
            {
                var mem = pool.Lease();

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

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

                PositiveAssert(mem, raw, expect);

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

                PositiveAssert(mem, "    ", "    ");

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

                PositiveAssert(mem, raw, expect);

                pool.Return(mem);
            }
        }
예제 #14
0
        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 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);
            }
        }
예제 #16
0
        public void IncomingDeferred()
        {
            Debug.Assert(_pinned != null);

            if (_pinned != null)
            {
                if (_pinned != _tail)
                {
                    _memory.Return(_pinned);
                }

                _pinned = null;
            }
        }
예제 #17
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 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);
            }
        }
예제 #19
0
        public static T Deserialize <T>(Stream stream, IJsonFormatterResolver resolver)
        {
            if (resolver == null)
            {
                resolver = DefaultResolver;
            }

#if NETSTANDARD && !NET45
            var ms = stream as MemoryStream;
            if (ms != null)
            {
                if (ms.TryGetBuffer(out var buf2))
                {
                    // when token is number, can not use from pool(can not find end line).
                    var token = new JsonReader(buf2.Array, buf2.Offset).GetCurrentJsonToken();
                    if (token == JsonToken.Number)
                    {
                        var buf3 = new byte[buf2.Count];
                        Buffer.BlockCopy(buf2.Array, buf2.Offset, buf3, 0, buf3.Length);
                        return(Deserialize <T>(buf3, 0, resolver));
                    }

                    return(Deserialize <T>(buf2.Array, buf2.Offset, resolver));
                }
            }
#endif
            {
                var buf     = MemoryPool.Rent();
                var poolBuf = buf;
                try
                {
                    var len = FillFromStream(stream, ref buf);

                    // when token is number, can not use from pool(can not find end line).
                    var token = new JsonReader(buf).GetCurrentJsonToken();
                    if (token == JsonToken.Number)
                    {
                        buf = BinaryUtil.FastCloneWithResize(buf, len);
                    }

                    return(Deserialize <T>(buf, resolver));
                }
                finally
                {
                    MemoryPool.Return(poolBuf);
                }
            }
        }
예제 #20
0
        public static byte[] PrettyPrintByteArray(byte[] json, int offset)
        {
            var reader = new JsonReader(json, offset);
            var buffer = MemoryPool.Rent();

            try
            {
                var writer = new JsonWriter(buffer);
                WritePrettyPrint(ref reader, ref writer, 0);
                return(writer.ToUtf8ByteArray());
            }
            finally
            {
                MemoryPool.Return(buffer);
            }
        }
예제 #21
0
        public static byte[] PrettyPrintByteArray(string json)
        {
            var reader = new JsonReader(Encoding.UTF8.GetBytes(json));
            var buffer = MemoryPool.Rent();

            try
            {
                var writer = new JsonWriter(buffer);
                WritePrettyPrint(ref reader, ref writer, 0);
                return(writer.ToUtf8ByteArray());
            }
            finally
            {
                MemoryPool.Return(buffer);
            }
        }
        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);
            }
        }
예제 #23
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);
            }
        }
예제 #24
0
        public void Serialize(Stream serializationStream, object graph)
        {
            IMessage message = (graph as IMessage);

            serializationStream.EncodeVariableInt(message.Id);

            PropertyManager.ReadLock();
            try
            {
                Dictionary <UInt32, PropertyContainer> .Enumerator iterator = PropertyManager.GetEnumerator();
                if (iterator.MoveNext())
                {
                    MemoryStream components = MemoryPool <MemoryStream> .Get();

                    try
                    {
                        do
                        {
                            object value; if (iterator.Current.Value.TryGet(message.Template, out value) && value != null && TypeFormatter.CanSerialize(value.GetType()))
                            {
                                components.Encode(iterator.Current.Key);
                                TypeFormatter.Serialize(components, value);

                                serializationStream.Encode(components.Length);
                                components.Seek(0, SeekOrigin.Begin);
                                components.CopyTo(serializationStream);
                                components.SetLength(0);
                            }
                        }while (iterator.MoveNext());
                    }
                    finally
                    {
                        MemoryPool <MemoryStream> .Return(components);
                    }
                }
            }
            finally
            {
                PropertyManager.ReadRelease();
            }
            serializationStream.Encode((long)0);
        }
예제 #25
0
        /// <summary>
        /// Serialize to binary with specified resolver.
        /// </summary>
        public static byte[] Serialize <T>(T value, IJsonFormatterResolver resolver)
        {
            if (resolver == null)
            {
                resolver = DefaultResolver;
            }
            var buffer = MemoryPool.Rent();

            try
            {
                var writer    = new JsonWriter(buffer);
                var formatter = resolver.GetFormatterWithVerify <T>();
                formatter.Serialize(ref writer, value, resolver);
                return(writer.ToUtf8ByteArray());
            }
            finally
            {
                MemoryPool.Return(buffer);
            }
        }
        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);
                }
            }
        }
예제 #27
0
        /// <summary>
        /// Serialize to stream(write async) with specified resolver.
        /// </summary>
        public static async System.Threading.Tasks.Task SerializeAsync <T>(Stream stream, T value, IJsonFormatterResolver resolver)
        {
            if (resolver == null)
            {
                resolver = DefaultResolver;
            }

            var buf = MemoryPool.Rent();

            try
            {
                var writer    = new JsonWriter(buf);
                var formatter = resolver.GetFormatterWithVerify <T>();
                formatter.Serialize(ref writer, value, resolver);
                var buffer = writer.GetBuffer();
                await stream.WriteAsync(buffer.Array, buffer.Offset, buffer.Count).ConfigureAwait(false);
            }
            finally
            {
                MemoryPool.Return(buf);
            }
        }
예제 #28
0
        /// <summary>
        /// Serialize to binary with specified resolver. Get the raw memory pool byte[]. The result can not share across thread and can not hold, so use quickly.
        /// </summary>
        public static ArraySegment <byte> SerializeUnsafe <T>(T value, IJsonFormatterResolver resolver)
        {
            if (resolver == null)
            {
                resolver = DefaultResolver;
            }

            var buffer = MemoryPool.Rent();

            try
            {
                var writer    = new JsonWriter(buffer);
                var formatter = resolver.GetFormatterWithVerify <T>();
                formatter.Serialize(ref writer, value, resolver);
                var arraySegment = writer.GetBuffer();
                return(new ArraySegment <byte>(BinaryUtil.ToArray(ref arraySegment)));
            }
            finally
            {
                MemoryPool.Return(buffer);
            }
        }
예제 #29
0
        public static async System.Threading.Tasks.Task <T> DeserializeAsync <T>(Stream stream, IJsonFormatterResolver resolver)
        {
            if (resolver == null)
            {
                resolver = DefaultResolver;
            }

            var buffer = MemoryPool.Rent();
            var buf    = buffer;

            try
            {
                int length = 0;
                int read;
                while ((read = await stream.ReadAsync(buf, length, buf.Length - length).ConfigureAwait(false)) > 0)
                {
                    length += read;
                    if (length == buf.Length)
                    {
                        BinaryUtil.FastResize(ref buf, length * 2);
                    }
                }

                // when token is number, can not use from pool(can not find end line).
                var token = new JsonReader(buf).GetCurrentJsonToken();
                if (token == JsonToken.Number)
                {
                    buf = BinaryUtil.FastCloneWithResize(buf, length);
                }

                return(Deserialize <T>(buf, resolver));
            }
            finally
            {
                MemoryPool.Return(buffer);
            }
        }
예제 #30
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();
        }