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); }
public void Exit() { InputScheduler.Add(delegate { ExitRequested = true; threads.ForEach(t => t.Exit()); while (threadsRunning) { Thread.Sleep(1); } Window?.Close(); }, false); }