public void Shutdown(UvStreamHandle handle, Action<UvShutdownReq, int, object> callback, object state)
 {
     _callback = callback;
     _state = state;
     _pin = GCHandle.Alloc(this, GCHandleType.Normal);
     _uv.shutdown(this, handle, _uv_shutdown_cb);
 }
 public void Shutdown(UvStreamHandle handle, Action<UvShutdownReq, int, object> callback, object state)
 {
     _callback = callback;
     _state = state;
     Pin();
     _uv.shutdown(this, handle, _uv_shutdown_cb);
 }
        public void Dispose()
        {
            // Ensure the event loop is still running.
            // If the event loop isn't running and we try to wait on this Post
            // to complete, then KestrelEngine will never be disposed and
            // the exception that stopped the event loop will never be surfaced.
            if (Thread.FatalError == null && ListenSocket != null)
            {
                var tcs = new TaskCompletionSource<int>();
                Thread.Post(
                    _ =>
                    {
                        try
                        {
                            ListenSocket.Dispose();
                            tcs.SetResult(0);
                        }
                        catch (Exception ex)
                        {
                            tcs.SetException(ex);
                        }
                    },
                    null);

                // REVIEW: Should we add a timeout here to be safe?
                tcs.Task.Wait();
            }

            ListenSocket = null;
        }
 public SocketOutput(KestrelThread thread, UvStreamHandle socket, long connectionId, IKestrelTrace log)
 {
     _thread = thread;
     _socket = socket;
     _connectionId = connectionId;
     _log = log;
     _callbacksPending = new Queue<CallbackContext>();
 }
        public unsafe void Write(
            UvStreamHandle handle,
            MemoryPoolIterator2 start,
            MemoryPoolIterator2 end,
            int nBuffers,
            Action<UvWriteReq, int, Exception, object> callback,
            object state)
        {
            try
            {
                // add GCHandle to keeps this SafeHandle alive while request processing
                _pins.Add(GCHandle.Alloc(this, GCHandleType.Normal));

                var pBuffers = (Libuv.uv_buf_t*)_bufs;
                if (nBuffers > BUFFER_COUNT)
                {
                    // create and pin buffer array when it's larger than the pre-allocated one
                    var bufArray = new Libuv.uv_buf_t[nBuffers];
                    var gcHandle = GCHandle.Alloc(bufArray, GCHandleType.Pinned);
                    _pins.Add(gcHandle);
                    pBuffers = (Libuv.uv_buf_t*)gcHandle.AddrOfPinnedObject();
                }

                var block = start.Block;
                for (var index = 0; index < nBuffers; index++)
                {
                    var blockStart = block == start.Block ? start.Index : block.Data.Offset;
                    var blockEnd = block == end.Block ? end.Index : block.Data.Offset + block.Data.Count;

                    // create and pin each segment being written
                    pBuffers[index] = Libuv.buf_init(
                        block.Pin() + blockStart,
                        blockEnd - blockStart);

                    block = block.Next;
                }

                _callback = callback;
                _state = state;
                _uv.write(this, handle, pBuffers, nBuffers, _uv_write_cb);
            }
            catch
            {
                _callback = null;
                _state = null;
                Unpin(this);

                var block = start.Block;
                for (var index = 0; index < nBuffers; index++)
                {
                    block.Unpin();
                    block = block.Next;
                }

                throw;
            }
        }
        public Connection(ListenerContext context, UvStreamHandle socket) : base(context)
        {
            _socket = socket;
            ConnectionControl = this;

            _connectionId = Interlocked.Increment(ref _lastConnectionId);

            _rawSocketInput = new SocketInput(Memory2, ThreadPool);
            _rawSocketOutput = new SocketOutput(Thread, _socket, Memory2, this, _connectionId, Log, ThreadPool, WriteReqPool);
        }
        public Connection(ListenerContext context, UvStreamHandle socket)
            : base(context)
        {
            _socket = socket;
            ConnectionControl = this;

            _connectionId = Interlocked.Increment(ref _lastConnectionId);

            SocketInput = new SocketInput(Memory2);
            SocketOutput = new SocketOutput(Thread, _socket, _connectionId, Log);
            _frame = new Frame(this);
        }
 protected static void ConnectionCallback(UvStreamHandle stream, int status, Exception error, object state)
 {
     var listener = (Listener) state;
     if (error != null)
     {
         listener.Log.LogError("Listener.ConnectionCallback ", error);
     }
     else
     {
         listener.OnConnection(stream, status);
     }
 }
        /// <summary>
        /// Handles an incoming connection
        /// </summary>
        /// <param name="listenSocket">Socket being used to listen on</param>
        /// <param name="status">Connection status</param>
        protected override void OnConnection(UvStreamHandle listenSocket, int status)
        {
            var acceptSocket = new UvPipeHandle(Log);
            acceptSocket.Init(Thread.Loop, false);

            try
            {
                listenSocket.Accept(acceptSocket);
            }
            catch (UvException ex)
            {
                Log.LogError("PipeListener.OnConnection", ex);
                return;
            }

            DispatchConnection(acceptSocket);
        }
        /// <summary>
        /// Handles an incoming connection
        /// </summary>
        /// <param name="listenSocket">Socket being used to listen on</param>
        /// <param name="status">Connection status</param>
        protected override void OnConnection(UvStreamHandle listenSocket, int status)
        {
            var acceptSocket = new UvTcpHandle(Log);
            acceptSocket.Init(Thread.Loop, Thread.QueueCloseHandle);

            try
            {
                listenSocket.Accept(acceptSocket);
            }
            catch (UvException ex)
            {
                Log.LogError("TcpListenerPrimary.OnConnection", ex);
                return;
            }

            DispatchConnection(acceptSocket);
        }
        public unsafe void Write(
            UvStreamHandle handle,
            ArraySegment<ArraySegment<byte>> bufs,
            Action<UvWriteReq, int, Exception, object> callback,
            object state)
        {
            try
            {
                // add GCHandle to keeps this SafeHandle alive while request processing
                _pins.Add(GCHandle.Alloc(this, GCHandleType.Normal));

                var pBuffers = (Libuv.uv_buf_t*)_bufs;
                var nBuffers = bufs.Count;
                if (nBuffers > BUFFER_COUNT)
                {
                    // create and pin buffer array when it's larger than the pre-allocated one
                    var bufArray = new Libuv.uv_buf_t[nBuffers];
                    var gcHandle = GCHandle.Alloc(bufArray, GCHandleType.Pinned);
                    _pins.Add(gcHandle);
                    pBuffers = (Libuv.uv_buf_t*)gcHandle.AddrOfPinnedObject();
                }

                for (var index = 0; index != nBuffers; ++index)
                {
                    // create and pin each segment being written
                    var buf = bufs.Array[bufs.Offset + index];

                    var gcHandle = GCHandle.Alloc(buf.Array, GCHandleType.Pinned);
                    _pins.Add(gcHandle);
                    pBuffers[index] = Libuv.buf_init(
                        gcHandle.AddrOfPinnedObject() + buf.Offset,
                        buf.Count);
                }

                _callback = callback;
                _state = state;
                _uv.write(this, handle, pBuffers, nBuffers, _uv_write_cb);
            }
            catch
            {
                _callback = null;
                _state = null;
                Unpin(this);
                throw;
            }
        }
        private void OnListenPipe(UvStreamHandle pipe, int status, Exception error, object state)
        {
            if (status < 0)
            {
                return;
            }

            var dispatchPipe = new UvPipeHandle();
            dispatchPipe.Init(Thread.Loop, true);
            try
            {
                pipe.Accept(dispatchPipe);
            }
            catch (Exception)
            {
                dispatchPipe.Dispose();
                return;
            }
            _dispatchPipes.Add(dispatchPipe);
        }
        private void OnListenPipe(UvStreamHandle pipe, int status, Exception error)
        {
            if (status < 0)
            {
                return;
            }

            var dispatchPipe = new UvPipeHandle(Log);
            dispatchPipe.Init(Thread.Loop, true);

            try
            {
                pipe.Accept(dispatchPipe);
            }
            catch (UvException ex)
            {
                dispatchPipe.Dispose();
                Log.LogError("ListenerPrimary.OnListenPipe", ex);
                return;
            }

            _dispatchPipes.Add(dispatchPipe);
        }
        public SocketOutput(
            KestrelThread thread,
            UvStreamHandle socket,
            MemoryPool2 memory,
            Connection connection,
            long connectionId,
            IKestrelTrace log,
            IThreadPool threadPool,
            Queue<UvWriteReq> writeReqPool)
        {
            _thread = thread;
            _socket = socket;
            _connection = connection;
            _connectionId = connectionId;
            _log = log;
            _threadPool = threadPool;
            _tasksPending = new Queue<TaskCompletionSource<object>>(_initialTaskQueues);
            _tasksCompleted = new Queue<TaskCompletionSource<object>>(_initialTaskQueues);
            _writeContextPool = new Queue<WriteContext>(_maxPooledWriteContexts);
            _writeReqPool = writeReqPool;

            _head = memory.Lease();
            _tail = _head;
        }
 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(Log);
         write.Init(Thread.Loop);
         write.Write2(
             dispatchPipe,
             _dummyMessage,
             socket,
             (write2, status, error, state) => 
             {
                 write2.Dispose();
                 ((UvStreamHandle)state).Dispose();
             },
             socket);
     }
 }
        public Task StartAsync(
            ServerAddress address,
            KestrelThread thread,
            Func<Frame, Task> application)
        {
            ServerAddress = address;
            Thread = thread;
            Application = application;

            var tcs = new TaskCompletionSource<int>();
            Thread.Post(_ =>
            {
                try
                {
                    ListenSocket = CreateListenSocket();
                    tcs.SetResult(0);
                }
                catch (Exception ex)
                {
                    tcs.SetException(ex);
                }
            }, null);
            return tcs.Task;
        }
Exemple #17
0
 public void shutdown(UvShutdownReq req, UvStreamHandle handle, uv_shutdown_cb cb)
 {
     req.Validate();
     handle.Validate();
     Check(_uv_shutdown(req, handle, cb));
 }
Exemple #18
0
 public int try_write(UvStreamHandle handle, Libuv.uv_buf_t[] bufs, int nbufs)
 {
     handle.Validate();
     return Check(_uv_try_write(handle, bufs, nbufs));
 }
Exemple #19
0
 public void shutdown(UvShutdownReq req, UvStreamHandle handle, uv_shutdown_cb cb)
 {
     req.Validate();
     handle.Validate();
     Check(_uv_shutdown(req, handle, cb));
 }
Exemple #20
0
 public void read_stop(UvStreamHandle handle)
 {
     handle.Validate();
     Check(_uv_read_stop(handle));
 }
 unsafe private int UvWrite(UvRequest req, UvStreamHandle handle, uv_buf_t* bufs, int nbufs, uv_write_cb cb)
 {
     return _onWrite(handle, new ArraySegment<ArraySegment<byte>>(), status => cb(req.InternalGetHandle(), status));
 }
 public SocketOutput(KestrelThread thread, UvStreamHandle socket)
 {
     _thread = thread;
     _socket = socket;
 }
Exemple #23
0
 public void read_start(UvStreamHandle handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb)
 {
     handle.Validate();
     Check(_uv_read_start(handle, alloc_cb, read_cb));
 }
 public SocketOutput(KestrelThread thread, UvStreamHandle socket)
 {
     _thread = thread;
     _socket = socket;
     _callbacksPending = new Queue<CallbackContext>();
 }
 unsafe public static extern int uv_write2(UvRequest req, UvStreamHandle handle, uv_buf_t* bufs, int nbufs, UvStreamHandle sendHandle, uv_write_cb cb);
 public static extern int uv_shutdown(UvShutdownReq req, UvStreamHandle handle, uv_shutdown_cb cb);
Exemple #27
0
 public void read_stop(UvStreamHandle handle)
 {
     handle.Validate();
     Check(_uv_read_stop(handle));
 }
Exemple #28
0
 public int try_write(UvStreamHandle handle, Libuv.uv_buf_t[] bufs, int nbufs)
 {
     handle.Validate();
     return(Check(_uv_try_write(handle, bufs, nbufs)));
 }
Exemple #29
0
 unsafe public void write(UvWriteReq req, UvStreamHandle handle, Libuv.uv_buf_t *bufs, int nbufs, uv_write_cb cb)
 {
     req.Validate();
     handle.Validate();
     Check(_uv_write(req, handle, bufs, nbufs, cb));
 }
Exemple #30
0
 public unsafe void write(UvWriteReq req, UvStreamHandle handle, Libuv.uv_buf_t* bufs, int nbufs, uv_write_cb cb)
 {
     req.Validate();
     handle.Validate();
     Check(_uv_write(req, handle, bufs, nbufs, cb));
 }
Exemple #31
0
 public void accept(UvStreamHandle server, UvStreamHandle client)
 {
     server.Validate();
     client.Validate();
     Check(_uv_accept(server, client));
 }
 public void Accept(UvStreamHandle handle)
 {
     _uv.accept(this, handle);
 }
Exemple #33
0
 public void accept(UvStreamHandle server, UvStreamHandle client)
 {
     server.Validate();
     client.Validate();
     Check(_uv_accept(server, client));
 }
Exemple #34
0
 public void listen(UvStreamHandle handle, int backlog, uv_connection_cb cb)
 {
     handle.Validate();
     Check(_uv_listen(handle, backlog, cb));
 }
Exemple #35
0
 public void listen(UvStreamHandle handle, int backlog, uv_connection_cb cb)
 {
     handle.Validate();
     Check(_uv_listen(handle, backlog, cb));
 }
 unsafe public void write2(UvRequest req, UvStreamHandle handle, Libuv.uv_buf_t *bufs, int nbufs, UvStreamHandle sendHandle, uv_write_cb cb)
 {
     req.Validate();
     handle.Validate();
     Check(_uv_write2(req, handle, bufs, nbufs, sendHandle, cb));
 }
Exemple #37
0
 public void read_start(UvStreamHandle handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb)
 {
     handle.Validate();
     Check(_uv_read_start(handle, alloc_cb, read_cb));
 }
 internal void Contextualize(
     SocketOutput socketOutput,
     UvStreamHandle socket,
     ArraySegment<byte> buffer,
     Action<Exception, object> callback,
     object state)
 {
     _self = socketOutput;
     _socket = socket;
     _buffer = buffer;
     _callback = callback;
     _state = state;
 }
Exemple #39
0
 public void Accept(UvStreamHandle handle)
 {
     _uv.accept(this, handle);
 }