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);
        }
Пример #2
0
 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();
     }
 }
Пример #3
0
        /// <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 { }
        }
Пример #5
0
        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);
            }
        }
Пример #6
0
 public void TestRunnerIsNotWorker()
 {
     Assert.False(DedicatedThreadPoolPipeScheduler.IsWorker());
     Assert.False(DedicatedThreadPoolPipeScheduler.IsWorker(DedicatedThreadPoolPipeScheduler.Default));
 }