Example #1
0
        internal SocketConnection(Socket socket,
                                  MemoryPool <byte> memoryPool,
                                  PipeScheduler scheduler,
                                  ISocketsTrace trace,
                                  long?maxReadBufferSize  = null,
                                  long?maxWriteBufferSize = null,
                                  bool deferSends         = true,
                                  bool deferReceives      = true,
                                  SocketContinuationScheduler socketScheduler = SocketContinuationScheduler.ThreadPool,
                                  InputScheduler inputScheduler             = InputScheduler.ThreadPool,
                                  bool dontAllocateMemoryForIdleConnections = true,
                                  OutputScheduler outputScheduler           = OutputScheduler.IOQueue)
        {
            Debug.Assert(socket != null);
            Debug.Assert(memoryPool != null);
            Debug.Assert(trace != null);

            _socket              = socket;
            MemoryPool           = memoryPool;
            _trace               = trace;
            _waitForReceiveReady = dontAllocateMemoryForIdleConnections;

            LocalEndPoint  = _socket.LocalEndPoint;
            RemoteEndPoint = _socket.RemoteEndPoint;

            ConnectionClosed = _connectionClosedTokenSource.Token;

            // On *nix platforms, Sockets already dispatches to the ThreadPool.
            // Yes, the IOQueues are still used for the PipeSchedulers. This is intentional.
            // https://github.com/aspnet/KestrelHttpServer/issues/2573
            var awaiterScheduler = IsWindows ? scheduler : PipeScheduler.Inline;

            _receiver = new SocketReceiver(_socket, awaiterScheduler, runContinuationsAsynchronously: socketScheduler == SocketContinuationScheduler.ThreadPool, preferSynchronousCompletion: !deferReceives);
            _sender   = new SocketSender(_socket, awaiterScheduler, runContinuationsAsynchronously: socketScheduler == SocketContinuationScheduler.ThreadPool, preferSynchronousCompletion: !deferSends);

            maxReadBufferSize ??= 0;
            maxWriteBufferSize ??= 0;

            PipeScheduler pipeScheduler = outputScheduler switch
            {
                OutputScheduler.Inline => PipeScheduler.Inline,
                OutputScheduler.IOQueue => scheduler,
                OutputScheduler.IOThread => _socket.IOThreadScheduler,
                OutputScheduler.ThreadPool => PipeScheduler.ThreadPool,
                _ => throw new IndexOutOfRangeException()
            };

            var appScheduler  = inputScheduler == InputScheduler.Inline ? PipeScheduler.Inline : PipeScheduler.ThreadPool;
            var inputOptions  = new PipeOptions(MemoryPool, appScheduler, scheduler, maxReadBufferSize.Value, maxReadBufferSize.Value / 2, useSynchronizationContext: false);
            var outputOptions = new PipeOptions(MemoryPool, pipeScheduler, appScheduler, maxWriteBufferSize.Value, maxWriteBufferSize.Value / 2, useSynchronizationContext: false);

            var pair = DuplexPipe.CreateConnectionPair(inputOptions, outputOptions);

            // Set the transport and connection id
            Transport   = pair.Transport;
            Application = pair.Application;
        }
        public void Exit()
        {
            InputScheduler.Add(delegate
            {
                ExitRequested = true;

                threads.ForEach(t => t.Exit());
                threads.Where(t => t.Running).ForEach(t => t.Thread.Join());
                Window?.Close();
            }, false);
        }
Example #3
0
        public void Exit()
        {
            InputScheduler.Add(delegate
            {
                ExitRequested = true;

                threads.ForEach(t => t.Exit());

                while (threadsRunning)
                {
                    Thread.Sleep(1);
                }
                Window?.Close();
            }, false);
        }