private SocketManager(string name, bool useHighPrioritySocketThreads, int workerCount) { if (string.IsNullOrWhiteSpace(name)) { name = GetType().Name; } Name = name; const long Receive_PauseWriterThreshold = 4L * 1024 * 1024 * 1024; // let's give it up to 4GiB of buffer for now const long Receive_ResumeWriterThreshold = 3L * 1024 * 1024 * 1024; var defaultPipeOptions = PipeOptions.Default; _schedulerPool = new DedicatedThreadPoolPipeScheduler(name + ":IO", workerCount: workerCount, priority: useHighPrioritySocketThreads ? ThreadPriority.AboveNormal : ThreadPriority.Normal); SendPipeOptions = new PipeOptions( pool: defaultPipeOptions.Pool, readerScheduler: _schedulerPool, writerScheduler: _schedulerPool, pauseWriterThreshold: defaultPipeOptions.PauseWriterThreshold, resumeWriterThreshold: defaultPipeOptions.ResumeWriterThreshold, minimumSegmentSize: Math.Max(defaultPipeOptions.MinimumSegmentSize, MINIMUM_SEGMENT_SIZE), useSynchronizationContext: false); ReceivePipeOptions = new PipeOptions( pool: defaultPipeOptions.Pool, readerScheduler: _schedulerPool, writerScheduler: _schedulerPool, pauseWriterThreshold: Receive_PauseWriterThreshold, resumeWriterThreshold: Receive_ResumeWriterThreshold, minimumSegmentSize: Math.Max(defaultPipeOptions.MinimumSegmentSize, MINIMUM_SEGMENT_SIZE), useSynchronizationContext: false); }
private void Dispose(bool disposing) { // note: the scheduler *can't* be collected by itself - there will // be threads, and those threads will be rooting the DedicatedThreadPool; // but: we can lend a hand! We need to do this even in the finalizer try { _schedulerPool?.Dispose(); } catch { } _schedulerPool = null; if (disposing) { GC.SuppressFinalize(this); OnDispose(); } }
/// <summary> /// Creates a new (optionally named) <see cref="SocketManager"/> instance. /// </summary> /// <param name="name">The name for this <see cref="SocketManager"/>.</param> /// <param name="workerCount">the number of dedicated workers for this <see cref="SocketManager"/>.</param> /// <param name="options"></param> public SocketManager(string name = null, int workerCount = 0, SocketManagerOptions options = SocketManagerOptions.None) { if (string.IsNullOrWhiteSpace(name)) { name = GetType().Name; } if (workerCount <= 0) { workerCount = DEFAULT_WORKERS; } Name = name; bool useHighPrioritySocketThreads = (options & SocketManagerOptions.UseHighPrioritySocketThreads) != 0, useThreadPool = (options & SocketManagerOptions.UseThreadPool) != 0; const long Receive_PauseWriterThreshold = 4L * 1024 * 1024 * 1024; // receive: let's give it up to 4GiB of buffer for now const long Receive_ResumeWriterThreshold = 3L * 1024 * 1024 * 1024; // (large replies get crazy big) var defaultPipeOptions = PipeOptions.Default; long Send_PauseWriterThreshold = Math.Max( 512 * 1024, // send: let's give it up to 0.5MiB defaultPipeOptions.PauseWriterThreshold); // or the default, whichever is bigger long Send_ResumeWriterThreshold = Math.Max( Send_PauseWriterThreshold / 2, defaultPipeOptions.ResumeWriterThreshold); Scheduler = PipeScheduler.ThreadPool; if (!useThreadPool) { Scheduler = new DedicatedThreadPoolPipeScheduler(name + ":IO", workerCount: workerCount, priority: useHighPrioritySocketThreads ? ThreadPriority.AboveNormal : ThreadPriority.Normal); } SendPipeOptions = new PipeOptions( pool: defaultPipeOptions.Pool, readerScheduler: Scheduler, writerScheduler: Scheduler, pauseWriterThreshold: Send_PauseWriterThreshold, resumeWriterThreshold: Send_ResumeWriterThreshold, minimumSegmentSize: Math.Max(defaultPipeOptions.MinimumSegmentSize, MINIMUM_SEGMENT_SIZE), useSynchronizationContext: false); ReceivePipeOptions = new PipeOptions( pool: defaultPipeOptions.Pool, readerScheduler: Scheduler, writerScheduler: Scheduler, pauseWriterThreshold: Receive_PauseWriterThreshold, resumeWriterThreshold: Receive_ResumeWriterThreshold, minimumSegmentSize: Math.Max(defaultPipeOptions.MinimumSegmentSize, MINIMUM_SEGMENT_SIZE), useSynchronizationContext: false); }
static PingPongTests() { // PipeOptions = PipeOptions.Default; var pool = new DedicatedThreadPoolPipeScheduler("Custom thread pool"); //var pool = PipeScheduler.Inline; //var pool = PipeScheduler.ThreadPool; PipeOptions = new PipeOptions(readerScheduler: pool, writerScheduler: pool, useSynchronizationContext: false); InlineSend = new PipeOptions(PipeOptions.Pool, PipeOptions.ReaderScheduler, PipeScheduler.Inline, PipeOptions.PauseWriterThreshold, PipeOptions.ResumeWriterThreshold, PipeOptions.MinimumSegmentSize, PipeOptions.UseSynchronizationContext); InlineReceive = new PipeOptions(PipeOptions.Pool, PipeScheduler.Inline, PipeOptions.WriterScheduler, PipeOptions.PauseWriterThreshold, PipeOptions.ResumeWriterThreshold, PipeOptions.MinimumSegmentSize, PipeOptions.UseSynchronizationContext); InlineBoth = new PipeOptions(PipeOptions.Pool, PipeScheduler.Inline, PipeScheduler.Inline, PipeOptions.PauseWriterThreshold, PipeOptions.ResumeWriterThreshold, PipeOptions.MinimumSegmentSize, PipeOptions.UseSynchronizationContext); try { _someCertificate = new X509Certificate2("somesite.pfx"); } catch { } }
public async Task PoolThreadIsWorker() { var defautPool = DedicatedThreadPoolPipeScheduler.Default; using (var newPool = new DedicatedThreadPoolPipeScheduler()) { var tcs = new TaskCompletionSource <bool>(); defautPool.Schedule( _ => tcs.SetResult(DedicatedThreadPoolPipeScheduler.IsWorker()), null); Assert.True(await tcs.Task); tcs = new TaskCompletionSource <bool>(); newPool.Schedule( _ => tcs.SetResult(DedicatedThreadPoolPipeScheduler.IsWorker()), null); Assert.True(await tcs.Task); tcs = new TaskCompletionSource <bool>(); defautPool.Schedule( _ => tcs.SetResult(DedicatedThreadPoolPipeScheduler.IsWorker(defautPool)), null); Assert.True(await tcs.Task); tcs = new TaskCompletionSource <bool>(); newPool.Schedule( _ => tcs.SetResult(DedicatedThreadPoolPipeScheduler.IsWorker(defautPool)), null); Assert.False(await tcs.Task); tcs = new TaskCompletionSource <bool>(); defautPool.Schedule( _ => tcs.SetResult(DedicatedThreadPoolPipeScheduler.IsWorker(newPool)), null); Assert.False(await tcs.Task); tcs = new TaskCompletionSource <bool>(); newPool.Schedule( _ => tcs.SetResult(DedicatedThreadPoolPipeScheduler.IsWorker(newPool)), null); Assert.True(await tcs.Task); } }
public void TestRunnerIsNotWorker() { Assert.False(DedicatedThreadPoolPipeScheduler.IsWorker()); Assert.False(DedicatedThreadPoolPipeScheduler.IsWorker(DedicatedThreadPoolPipeScheduler.Default)); }