Пример #1
0
            /// <summary>
            /// First step: initiate async write if needed, otherwise go to next step
            /// </summary>
            public void DoWriteIfNeeded()
            {
                LockWrite();

                if (ByteCount == 0 || Self._socket.IsClosed)
                {
                    DoShutdownIfNeeded();
                    return;
                }

                // Update _head immediate after write is "locked", so the block returning logic
                // works correctly when run inline in the write callback.
                Self._head       = _lockedEnd.Block;
                Self._head.Start = _lockedEnd.Index;

                _writeReq = Self._writeReqPool.Allocate();

                _writeReq.Write(Self._socket, _lockedStart, _lockedEnd, _bufferCount, (req, status, error, state) =>
                {
                    var writeContext = (WriteContext)state;
                    writeContext.PoolWriteReq(writeContext._writeReq);
                    writeContext._writeReq = null;
                    writeContext.ScheduleReturnWrittenBlocks();
                    writeContext.WriteStatus = status;
                    writeContext.WriteError  = error;
                    writeContext.DoShutdownIfNeeded();
                }, this);
            }
Пример #2
0
            /// <summary>
            /// First step: initiate async write if needed, otherwise go to next step
            /// </summary>
            public void DoWriteIfNeeded()
            {
                if (Buffers.Count == 0 || Self._socket.IsClosed)
                {
                    DoShutdownIfNeeded();
                    return;
                }

                var buffers = new ArraySegment <byte> [Buffers.Count];

                var i = 0;

                foreach (var buffer in Buffers)
                {
                    buffers[i++] = buffer;
                }

                var writeReq = new UvWriteReq(Self._log);

                writeReq.Init(Self._thread.Loop);
                writeReq.Write(Self._socket, new ArraySegment <ArraySegment <byte> >(buffers), (_writeReq, status, error, state) =>
                {
                    _writeReq.Dispose();
                    var _this         = (WriteContext)state;
                    _this.WriteStatus = status;
                    _this.WriteError  = error;
                    DoShutdownIfNeeded();
                }, this);
            }
Пример #3
0
        private static void WriteCallback(UvWriteReq req, int status, Exception ex, object state)
        {
            var connection = ((UvTcpConnection)state);

            connection._outgoing.Dequeue().Dispose();
            connection._connectionCompleted?.TrySetResult(null);
        }
Пример #4
0
        protected override void DispatchConnection(UvStreamHandle socket)
        {
            var index = _dispatchIndex++ % (_dispatchPipes.Count + 1);

            if (index == _dispatchPipes.Count)
            {
                base.DispatchConnection(socket);
            }
            else
            {
                var dispatchPipe = _dispatchPipes[index];
                var write        = new UvWriteReq();
                write.Init(Thread.Loop);
                write.Write2(
                    dispatchPipe,
                    _dummyMessage,
                    socket,
                    (write2, status, error, state) =>
                {
                    write2.Dispose();
                    ((UvStreamHandle)state).Dispose();
                },
                    socket);
            }
        }
Пример #5
0
        protected override void DispatchConnection(UvStreamHandle socket)
        {
            var index = _dispatchIndex++ % (_dispatchPipes.Count + 1);

            if (index == _dispatchPipes.Count)
            {
                base.DispatchConnection(socket);
            }
            else
            {
                DetachFromIOCP(socket);
                var dispatchPipe = _dispatchPipes[index];
                var write        = new UvWriteReq(Log);
                try
                {
                    write.Init(Thread);
                    write.Write2(
                        dispatchPipe,
                        _dummyMessage,
                        socket,
                        (write2, status, error, state) =>
                    {
                        write2.Dispose();
                        ((UvStreamHandle)state).Dispose();
                    },
                        socket);
                }
                catch (UvException)
                {
                    write.Dispose();
                    throw;
                }
            }
        }
Пример #6
0
 private void PoolWriteReq(UvWriteReq writeReq)
 {
     if (Self._writeReqPool.Count < MaxPooledWriteReqs)
     {
         Self._writeReqPool.Enqueue(writeReq);
     }
     else
     {
         writeReq.Dispose();
     }
 }
Пример #7
0
        private void EndWrite(UvWriteReq writeReq)
        {
            _pendingWrites--;

            _thread.WriteReqPool.Return(writeReq);

            if (_drainWrites != null)
            {
                if (_pendingWrites == 0)
                {
                    _drainWrites.TrySetResult(null);
                }
            }
        }
Пример #8
0
        private async Task ProcessWrites()
        {
            var writeReq = new UvWriteReq();

            writeReq.Init(_thread.Loop);

            try
            {
                while (true)
                {
                    var buffer = await _output;

                    // Make sure we're on the libuv thread
                    await _thread;

                    if (buffer.IsEmpty && _output.Completion.IsCompleted)
                    {
                        break;
                    }

                    // Up the reference count of the buffer so that we own the disposal of it
                    var cloned = buffer.Clone();
                    _outgoing.Enqueue(cloned);
                    writeReq.Write(_handle, ref cloned, _writeCallback, this);

                    buffer.Consumed();
                }
            }
            catch (Exception ex)
            {
                _output.CompleteReading(ex);
            }
            finally
            {
                _output.CompleteReading();

                // There's pending writes happening
                if (_outgoing.Count > 0)
                {
                    _connectionCompleted = new TaskCompletionSource <object>();

                    await _connectionCompleted.Task;
                }

                writeReq.Dispose();

                _handle.Dispose();
            }
        }
Пример #9
0
            private void OnWrite(UvWriteReq req, int status, Exception error)
            {
                KestrelTrace.Log.ConnectionWriteCallback(0, status);
                //NOTE: pool this?

                var callback = _callback;

                _callback = null;
                var state = _state;

                _state = null;

                Dispose();
                callback(error, state);
            }
Пример #10
0
        private async Task ProcessWrites(UvLoopHandle loop, UvTcpHandle handle)
        {
            var writeReq = new UvWriteReq();

            writeReq.Init(loop);

            try
            {
                while (true)
                {
                    await _output;

                    var buffer = _output.BeginRead();

                    if (buffer.IsEmpty && _output.Completion.IsCompleted)
                    {
                        break;
                    }

                    // Up the reference count of the buffer so that we own the disposal of it
                    var cloned = buffer.Clone();
                    _outgoing.Enqueue(cloned);
                    writeReq.Write(handle, ref cloned, _writeCallback, this);

                    _output.EndRead(buffer);
                }
            }
            catch (Exception ex)
            {
                _output.CompleteReading(ex);
            }
            finally
            {
                _output.CompleteReading();

                // There's pending writes happening
                if (_outgoing.Count > 0)
                {
                    _connectionCompleted = new TaskCompletionSource <object>();

                    await _connectionCompleted.Task;
                }

                writeReq.Dispose();

                handle.Dispose();
            }
        }
Пример #11
0
        public void Return(UvWriteReq req)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            if (_pool.Count < _maxPooledWriteReqs)
            {
                _pool.Enqueue(req);
            }
            else
            {
                req.Dispose();
            }
        }
Пример #12
0
        private void ConnectedCallback(UvConnectRequest connect, int status, Exception error, TaskCompletionSource <int> tcs)
        {
            connect.Dispose();
            if (error != null)
            {
                tcs.SetException(error);
                return;
            }

            var writeReq = new UvWriteReq(Log);

            try
            {
                DispatchPipe.ReadStart(
                    (handle, status2, state) => ((ListenerSecondary)state)._buf,
                    (handle, status2, state) => ((ListenerSecondary)state).ReadStartCallback(handle, status2),
                    this);

                writeReq.Init(Thread.Loop);
                writeReq.Write(
                    DispatchPipe,
                    new ArraySegment <ArraySegment <byte> >(new [] { new ArraySegment <byte>(_pipeMessage) }),
                    (req, status2, ex, state) =>
                {
                    req.Dispose();

                    if (ex != null)
                    {
                        tcs.SetException(ex);
                    }
                    else
                    {
                        tcs.SetResult(0);
                    }
                },
                    tcs);
            }
            catch (Exception ex)
            {
                writeReq.Dispose();
                DispatchPipe.Dispose();
                tcs.SetException(ex);
            }
        }
Пример #13
0
        private async Task ConnectedCallback(UvConnectRequest connect, int status, UvException error, TaskCompletionSource <int> tcs)
        {
            connect.Dispose();
            if (error != null)
            {
                tcs.SetException(error);
                return;
            }

            var writeReq = new UvWriteReq(Log);

            try
            {
                DispatchPipe.ReadStart(
                    (handle, status2, state) => ((ListenerSecondary)state)._buf,
                    (handle, status2, state) => ((ListenerSecondary)state).ReadStartCallback(handle, status2),
                    this);

                writeReq.Init(Thread);
                var result = await writeReq.WriteAsync(
                    DispatchPipe,
                    new ArraySegment <ArraySegment <byte> >(new[] { new ArraySegment <byte>(_pipeMessage) }));

                if (result.Error != null)
                {
                    tcs.SetException(result.Error);
                }
                else
                {
                    tcs.SetResult(0);
                }
            }
            catch (Exception ex)
            {
                DispatchPipe.Dispose();
                tcs.SetException(ex);
            }
            finally
            {
                writeReq.Dispose();
            }
        }
Пример #14
0
        private static void WriteCallback(UvWriteReq req, int status, Exception ex, object state)
        {
            var connection = ((UvTcpConnection)state);

            var buffer = connection._outgoing.Dequeue();

            // Dispose the preserved buffer
            buffer.Dispose();

            // Return the WriteReq
            connection._thread.WriteReqPool.Return(req);

            if (connection._drainWrites != null)
            {
                if (connection._outgoing.Count == 0)
                {
                    connection._drainWrites.TrySetResult(null);
                }
            }
        }
Пример #15
0
        public UvWriteReq Allocate()
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            UvWriteReq req;

            if (_pool.Count > 0)
            {
                req = _pool.Dequeue();
            }
            else
            {
                req = new UvWriteReq(_log);
                req.Init(_thread);
            }

            return(req);
        }
Пример #16
0
            /// <summary>
            /// First step: initiate async write if needed, otherwise go to next step
            /// </summary>
            public void DoWriteIfNeeded()
            {
                LockWrite();

                if (ByteCount == 0 || Self._socket.IsClosed)
                {
                    DoShutdownIfNeeded();
                    return;
                }

                // Sample values locally in case write completes inline
                // to allow block to be Reset and still complete this function
                var lockedEndBlock = _lockedEnd.Block;
                var lockedEndIndex = _lockedEnd.Index;

                if (Self._writeReqPool.Count > 0)
                {
                    _writeReq = Self._writeReqPool.Dequeue();
                }
                else
                {
                    _writeReq = new UvWriteReq(Self._log);
                    _writeReq.Init(Self._thread.Loop);
                }

                _writeReq.Write(Self._socket, _lockedStart, _lockedEnd, _bufferCount, (_writeReq, status, error, state) =>
                {
                    var writeContext = (WriteContext)state;
                    writeContext.PoolWriteReq(writeContext._writeReq);
                    writeContext._writeReq = null;
                    writeContext.ScheduleReturnFullyWrittenBlocks();
                    writeContext.WriteStatus = status;
                    writeContext.WriteError  = error;
                    writeContext.DoShutdownIfNeeded();
                }, this);

                Self._head       = lockedEndBlock;
                Self._head.Start = lockedEndIndex;
            }
Пример #17
0
        public async Task SocketCanReadAndWrite()
        {
            var loop = new UvLoopHandle(_logger);

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

            tcp.Init(loop, (a, b) => { });
            var endPoint = new IPEndPoint(IPAddress.Loopback, 0);

            tcp.Bind(endPoint);
            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),
                    async(__, nread, state2) =>
                {
                    if (nread <= 0)
                    {
                        tcp2.Dispose();
                    }
                    else
                    {
                        for (var x = 0; x < 2; x++)
                        {
                            var req = new UvWriteReq(_logger);
                            req.DangerousInit(loop);
                            var block = new ReadOnlyBuffer <byte>(new byte[] { 65, 66, 67, 68, 69 });

                            await req.WriteAsync(
                                tcp2,
                                block);
                        }
                    }
                },
                    null);
                tcp.Dispose();
            }, null);
            var t = Task.Run(async() =>
            {
                var socket = TestConnection.CreateConnectedLoopbackSocket(port);
                await socket.SendAsync(new[] { new ArraySegment <byte>(new byte[] { 1, 2, 3, 4, 5 }) },
                                       SocketFlags.None);
                socket.Shutdown(SocketShutdown.Send);
                var buffer = new ArraySegment <byte>(new byte[2048]);
                while (true)
                {
                    var count = await socket.ReceiveAsync(new[] { buffer }, SocketFlags.None);
                    if (count <= 0)
                    {
                        break;
                    }
                }
                socket.Dispose();
            });

            loop.Run();
            loop.Dispose();
            await t;
        }
Пример #18
0
        public void ServerPipeListenForConnections()
        {
            var loop             = new UvLoopHandle(_logger);
            var serverListenPipe = new UvPipeHandle(_logger);

            loop.Init(_uv);
            serverListenPipe.Init(loop, false);
            serverListenPipe.Bind(@"\\.\pipe\ServerPipeListenForConnections");
            serverListenPipe.Listen(128, (_1, status, error, _2) =>
            {
                var serverConnectionPipe = new UvPipeHandle(_logger);
                serverConnectionPipe.Init(loop, true);
                try
                {
                    serverListenPipe.Accept(serverConnectionPipe);
                }
                catch (Exception)
                {
                    serverConnectionPipe.Dispose();
                    return;
                }

                var writeRequest = new UvWriteReq(new KestrelTrace(new TestKestrelTrace()));
                writeRequest.Init(loop);
                var block = MemoryPoolBlock2.Create(
                    new ArraySegment <byte>(new byte[] { 1, 2, 3, 4 }),
                    dataPtr: IntPtr.Zero,
                    pool: null,
                    slab: null);
                var start = new MemoryPoolIterator2(block, 0);
                var end   = new MemoryPoolIterator2(block, block.Data.Count);
                writeRequest.Write(
                    serverConnectionPipe,
                    start,
                    end,
                    1,
                    (_3, status2, error2, _4) =>
                {
                    writeRequest.Dispose();
                    serverConnectionPipe.Dispose();
                    serverListenPipe.Dispose();
                    block.Unpin();
                },
                    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, true);
                connect.Init(loop2);
                connect.Connect(clientConnectionPipe, @"\\.\pipe\ServerPipeListenForConnections", (_1, status, error, _2) =>
                {
                    var buf = loop2.Libuv.buf_init(Marshal.AllocHGlobal(8192), 8192);

                    connect.Dispose();
                    clientConnectionPipe.ReadStart(
                        (_3, cb, _4) => buf,
                        (_3, status2, _4) =>
                    {
                        if (status2 == 0)
                        {
                            clientConnectionPipe.Dispose();
                        }
                    },
                        null);
                }, null);
                loop2.Run();
                loop2.Dispose();
            });

            worker.Start();
            loop.Run();
            loop.Dispose();
            worker.Join();
        }
        public async Task SocketCanReadAndWrite()
        {
            var loop = new UvLoopHandle(_logger);

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

            tcp.Init(loop);
            var address = ServerAddress.FromUrl("http://localhost:54321/");

            tcp.Bind(address);
            tcp.Listen(10, (_, status, error, state) =>
            {
                Console.WriteLine("Connected");
                var tcp2 = new UvTcpHandle(_logger);
                tcp2.Init(loop);
                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 block = MemoryPoolBlock2.Create(
                                new ArraySegment <byte>(new byte[] { 65, 66, 67, 68, 69 }),
                                dataPtr: IntPtr.Zero,
                                pool: null,
                                slab: null);
                            var start = new MemoryPoolIterator2(block, 0);
                            var end   = new MemoryPoolIterator2(block, block.Data.Count);
                            req.Write(
                                tcp2,
                                start,
                                end,
                                1,
                                (_1, _2, _3, _4) =>
                            {
                                block.Unpin();
                            },
                                null);
                        }
                    }
                },
                    null);
                tcp.Dispose();
            }, null);
            Console.WriteLine("Task.Run");
            var t = Task.Run(async() =>
            {
                var socket = new Socket(
                    AddressFamily.InterNetwork,
                    SocketType.Stream,
                    ProtocolType.Tcp);
#if DNX451
                await Task.Factory.FromAsync(
                    socket.BeginConnect,
                    socket.EndConnect,
                    new IPEndPoint(IPAddress.Loopback, 54321),
                    null,
                    TaskCreationOptions.None);
                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.ConnectAsync(new IPEndPoint(IPAddress.Loopback, 54321));
                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 DNX451
                    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
                    Console.WriteLine("count {0} {1}",
                                      count,
                                      System.Text.Encoding.ASCII.GetString(buffer.Array, 0, count));
                    if (count <= 0)
                    {
                        break;
                    }
                }
                socket.Dispose();
            });

            loop.Run();
            loop.Dispose();
            await t;
        }
Пример #20
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, async(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(_logger);
                writeRequest.DangerousInit(loop);

                await writeRequest.WriteAsync(
                    serverConnectionPipe,
                    new ReadOnlyBuffer(new byte[] { 1, 2, 3, 4 }));

                writeRequest.Dispose();
                serverConnectionPipe.Dispose();
                serverListenPipe.Dispose();
            }, null);

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

                loop2.Init(_uv);
                clientConnectionPipe.Init(loop2, (a, b) => { }, true);
                connect.DangerousInit(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 == TestConstants.EOF)
                        {
                            clientConnectionPipe.Dispose();
                        }
                    },
                        null);
                }, null);
                loop2.Run();
                loop2.Dispose();
            });

            worker.Start();
            loop.Run();
            loop.Dispose();
            worker.Join();
        }
Пример #21
0
 private static void WriteCallback(UvWriteReq req, int status, Exception error, object state)
 {
     ((ThisWriteReq)state).OnWrite(req, status, error);
 }
Пример #22
0
 private static void WriteCallback(UvWriteReq writeReq, int status, object state)
 {
     ((UvTcpConnection)state).EndWrite(writeReq);
 }
Пример #23
0
 private void PoolWriteReq(UvWriteReq writeReq)
 {
     Self._writeReqPool.Return(writeReq);
 }
        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;
        }
Пример #25
0
        public void ServerPipeDispatchConnections()
        {
            var pipeName = @"\\.\pipe\ServerPipeDispatchConnections" + Guid.NewGuid().ToString("n");

            var loop = new UvLoopHandle(_logger);

            loop.Init(_uv);

            var serverConnectionPipe = default(UvPipeHandle);
            var serverConnectionPipeAcceptedEvent = new ManualResetEvent(false);
            var serverConnectionTcpDisposedEvent  = new ManualResetEvent(false);

            var serverListenPipe = new UvPipeHandle(_logger);

            serverListenPipe.Init(loop, false);
            serverListenPipe.Bind(pipeName);
            serverListenPipe.Listen(128, (_1, status, error, _2) =>
            {
                serverConnectionPipe = new UvPipeHandle(_logger);
                serverConnectionPipe.Init(loop, true);
                try
                {
                    serverListenPipe.Accept(serverConnectionPipe);
                    serverConnectionPipeAcceptedEvent.Set();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    serverConnectionPipe.Dispose();
                    serverConnectionPipe = null;
                }
            }, null);

            var serverListenTcp = new UvTcpHandle(_logger);

            serverListenTcp.Init(loop);
            var address = ServerAddress.FromUrl("http://localhost:54321/");

            serverListenTcp.Bind(address);
            serverListenTcp.Listen(128, (_1, status, error, _2) =>
            {
                var serverConnectionTcp = new UvTcpHandle(_logger);
                serverConnectionTcp.Init(loop);
                serverListenTcp.Accept(serverConnectionTcp);

                serverConnectionPipeAcceptedEvent.WaitOne();

                var writeRequest = new UvWriteReq(new KestrelTrace(new TestKestrelTrace()));
                writeRequest.Init(loop);
                writeRequest.Write2(
                    serverConnectionPipe,
                    new ArraySegment <ArraySegment <byte> >(new ArraySegment <byte>[] { new ArraySegment <byte>(new byte[] { 1, 2, 3, 4 }) }),
                    serverConnectionTcp,
                    (_3, status2, error2, _4) =>
                {
                    writeRequest.Dispose();
                    serverConnectionTcp.Dispose();
                    serverConnectionTcpDisposedEvent.Set();
                    serverConnectionPipe.Dispose();
                    serverListenPipe.Dispose();
                    serverListenTcp.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, true);
                connect.Init(loop2);
                connect.Connect(clientConnectionPipe, pipeName, (_1, status, error, _2) =>
                {
                    connect.Dispose();

                    var buf = loop2.Libuv.buf_init(Marshal.AllocHGlobal(64), 64);

                    serverConnectionTcpDisposedEvent.WaitOne();

                    clientConnectionPipe.ReadStart(
                        (_3, cb, _4) => buf,
                        (_3, status2, _4) =>
                    {
                        if (status2 == 0)
                        {
                            clientConnectionPipe.Dispose();
                            return;
                        }
                        var clientConnectionTcp = new UvTcpHandle(_logger);
                        clientConnectionTcp.Init(loop2);
                        clientConnectionPipe.Accept(clientConnectionTcp);
                        var buf2 = loop2.Libuv.buf_init(Marshal.AllocHGlobal(64), 64);
                        clientConnectionTcp.ReadStart(
                            (_5, cb, _6) => buf2,
                            (_5, status3, _6) =>
                        {
                            if (status3 == 0)
                            {
                                clientConnectionTcp.Dispose();
                            }
                        },
                            null);
                    },
                        null);
                }, null);
                loop2.Run();
                loop2.Dispose();
            });

            var worker2 = new Thread(() =>
            {
                try
                {
                    serverConnectionPipeAcceptedEvent.WaitOne();

                    var socket = new Socket(SocketType.Stream, ProtocolType.IP);
                    socket.Connect(IPAddress.Loopback, 54321);
                    socket.Send(new byte[] { 6, 7, 8, 9 });
                    socket.Shutdown(SocketShutdown.Send);
                    var cb = socket.Receive(new byte[64]);
                    socket.Dispose();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            });

            worker.Start();
            worker2.Start();

            loop.Run();
            loop.Dispose();
            worker.Join();
            worker2.Join();
        }
Пример #26
0
        public void ServerPipeDispatchConnections()
        {
            var pipeName = @"\\.\pipe\ServerPipeDispatchConnections" + Guid.NewGuid().ToString("n");

            var loop = new UvLoopHandle(_logger);

            loop.Init(_uv);

            var serverConnectionPipe = default(UvPipeHandle);
            var serverConnectionPipeAcceptedEvent = new ManualResetEvent(false);
            var serverConnectionTcpDisposedEvent  = new ManualResetEvent(false);

            var serverListenPipe = new UvPipeHandle(_logger);

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

                try
                {
                    serverListenPipe.Accept(serverConnectionPipe);
                    serverConnectionPipeAcceptedEvent.Set();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    serverConnectionPipe.Dispose();
                    serverConnectionPipe = null;
                }
            }, null);

            var serverListenTcp = new UvTcpHandle(_logger);

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

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

            serverListenTcp.Listen(128, (handle, status, error, state) =>
            {
                var serverConnectionTcp = new UvTcpHandle(_logger);
                serverConnectionTcp.Init(loop, (a, b) => { });
                serverListenTcp.Accept(serverConnectionTcp);

                serverConnectionPipeAcceptedEvent.WaitOne();

                var writeRequest = new UvWriteReq(new KestrelTrace(new TestKestrelTrace()));
                writeRequest.Init(loop);
                writeRequest.Write2(
                    serverConnectionPipe,
                    new ArraySegment <ArraySegment <byte> >(new ArraySegment <byte>[] { new ArraySegment <byte>(new byte[] { 1, 2, 3, 4 }) }),
                    serverConnectionTcp,
                    (handle2, status2, error2, state2) =>
                {
                    writeRequest.Dispose();
                    serverConnectionTcp.Dispose();
                    serverConnectionTcpDisposedEvent.Set();
                    serverConnectionPipe.Dispose();
                    serverListenPipe.Dispose();
                    serverListenTcp.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) =>
                {
                    connect.Dispose();

                    var buf = loop2.Libuv.buf_init(Marshal.AllocHGlobal(64), 64);

                    serverConnectionTcpDisposedEvent.WaitOne();

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

                        var clientConnectionTcp = new UvTcpHandle(_logger);
                        clientConnectionTcp.Init(loop2, (a, b) => { });
                        clientConnectionPipe.Accept(clientConnectionTcp);
                        var buf2 = loop2.Libuv.buf_init(Marshal.AllocHGlobal(64), 64);
                        clientConnectionTcp.ReadStart(
                            (handle3, cb, state3) => buf2,
                            (handle3, status3, state3) =>
                        {
                            if (status3 == Constants.EOF)
                            {
                                clientConnectionTcp.Dispose();
                            }
                        },
                            null);
                    },
                        null);
                }, null);
                loop2.Run();
                loop2.Dispose();
            });

            var worker2 = new Thread(() =>
            {
                try
                {
                    serverConnectionPipeAcceptedEvent.WaitOne();

                    var socket = TestConnection.CreateConnectedLoopbackSocket(port);
                    socket.Send(new byte[] { 6, 7, 8, 9 });
                    socket.Shutdown(SocketShutdown.Send);
                    var cb = socket.Receive(new byte[64]);
                    socket.Dispose();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            });

            worker.Start();
            worker2.Start();

            loop.Run();
            loop.Dispose();
            worker.Join();
            worker2.Join();
        }
Пример #27
0
        public async Task SocketCanReadAndWrite()
        {
            int bytesRead = 0;
            var loop      = new UvLoopHandle();

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

            tcp.Init(loop);
            tcp.Bind(new IPEndPoint(IPAddress.Loopback, 54321));
            tcp.Listen(10, (_, status, error, state) =>
            {
                Console.WriteLine("Connected");
                var tcp2 = new UvTcpHandle();
                tcp2.Init(loop);
                tcp.Accept(tcp2);
                var data = Marshal.AllocCoTaskMem(500);
                tcp2.ReadStart(
                    (a, b, c) => tcp2.Libuv.buf_init(data, 500),
                    (__, nread, error2, state2) =>
                {
                    bytesRead += nread;
                    if (nread == 0)
                    {
                        tcp2.Dispose();
                    }
                    else
                    {
                        for (var x = 0; x != 2; ++x)
                        {
                            var req = new UvWriteReq();
                            req.Init(loop);
                            req.Write(
                                tcp2,
                                new ArraySegment <ArraySegment <byte> >(
                                    new[] { new ArraySegment <byte>(new byte[] { 65, 66, 67, 68, 69 }) }
                                    ),
                                (_1, _2, _3, _4) => { },
                                null);
                        }
                    }
                },
                    null);
                tcp.Dispose();
            }, null);
            Console.WriteLine("Task.Run");
            var t = Task.Run(async() =>
            {
                var socket = new Socket(
                    AddressFamily.InterNetwork,
                    SocketType.Stream,
                    ProtocolType.Tcp);
                await Task.Factory.FromAsync(
                    socket.BeginConnect,
                    socket.EndConnect,
                    new IPEndPoint(IPAddress.Loopback, 54321),
                    null,
                    TaskCreationOptions.None);
                await Task.Factory.FromAsync(
                    socket.BeginSend,
                    socket.EndSend,
                    new[] { new ArraySegment <byte>(new byte[] { 1, 2, 3, 4, 5 }) },
                    SocketFlags.None,
                    null,
                    TaskCreationOptions.None);
                socket.Shutdown(SocketShutdown.Send);
                var buffer = new ArraySegment <byte>(new byte[2048]);
                for (; ;)
                {
                    var count = await Task.Factory.FromAsync(
                        socket.BeginReceive,
                        socket.EndReceive,
                        new[] { buffer },
                        SocketFlags.None,
                        null,
                        TaskCreationOptions.None);
                    Console.WriteLine("count {0} {1}",
                                      count,
                                      System.Text.Encoding.ASCII.GetString(buffer.Array, 0, count));
                    if (count <= 0)
                    {
                        break;
                    }
                }
                socket.Dispose();
            });

            loop.Run();
            loop.Dispose();
            await t;
        }
Пример #28
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();
        }
Пример #29
0
        public void ServerPipeListenForConnections()
        {
            var loop             = new UvLoopHandle(_logger);
            var serverListenPipe = new UvPipeHandle(_logger);

            loop.Init(_uv);
            serverListenPipe.Init(loop, false);
            serverListenPipe.Bind(@"\\.\pipe\ServerPipeListenForConnections");
            serverListenPipe.Listen(128, (_1, status, error, _2) =>
            {
                var serverConnectionPipe = new UvPipeHandle(_logger);
                serverConnectionPipe.Init(loop, true);
                try
                {
                    serverListenPipe.Accept(serverConnectionPipe);
                }
                catch (Exception)
                {
                    serverConnectionPipe.Dispose();
                    return;
                }

                var writeRequest = new UvWriteReq(new KestrelTrace(new TestKestrelTrace()));
                writeRequest.Init(loop);
                writeRequest.Write(
                    serverConnectionPipe,
                    new ArraySegment <ArraySegment <byte> >(new ArraySegment <byte>[] { new ArraySegment <byte>(new byte[] { 1, 2, 3, 4 }) }),
                    (_3, status2, error2, _4) =>
                {
                    writeRequest.Dispose();
                    serverConnectionPipe.Dispose();
                    serverListenPipe.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, true);
                connect.Init(loop2);
                connect.Connect(clientConnectionPipe, @"\\.\pipe\ServerPipeListenForConnections", (_1, status, error, _2) =>
                {
                    var buf = loop2.Libuv.buf_init(Marshal.AllocHGlobal(8192), 8192);

                    connect.Dispose();
                    clientConnectionPipe.ReadStart(
                        (_3, cb, _4) => buf,
                        (_3, status2, errCode, error2, _4) =>
                    {
                        if (status2 == 0)
                        {
                            clientConnectionPipe.Dispose();
                        }
                    },
                        null);
                }, null);
                loop2.Run();
                loop2.Dispose();
            });

            worker.Start();
            loop.Run();
            loop.Dispose();
            worker.Join();
        }