Esempio n. 1
0
        void DestroyDown(XThread currentThread, FABHandlerContext ctx, bool inEventLoop)
        {
            // We have reached at tail; now traverse backwards.
            FABHandlerContext headContext = this.head;

            while (true)
            {
                if (ctx == headContext)
                {
                    break;
                }

                IEventExecutor executor = ctx.Executor;
                if (inEventLoop || executor.IsInEventLoop(currentThread))
                {
                    lock (this)
                    {
                        Remove0(ctx);
                        this.CallHandlerRemoved0(ctx);
                    }
                }
                else
                {
                    executor.Execute((self, c) => ((FABChannelPipeline)self).DestroyDown(XThread.CurrentThread, (FABHandlerContext)c, true), this, ctx);
                    break;
                }

                ctx         = ctx.Prev;
                inEventLoop = false;
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Creates a new timer.
        /// </summary>
        /// <param name="tickInterval">the interval between two consecutive ticks</param>
        /// <param name="ticksPerWheel">the size of the wheel</param>
        /// <param name="maxPendingTimeouts">The maximum number of pending timeouts after which call to
        /// <c>newTimeout</c> will result in <see cref="RejectedExecutionException"/> being thrown.
        /// No maximum pending timeouts limit is assumed if this value is 0 or negative.</param>
        /// <exception cref="ArgumentException">if either of <c>tickInterval</c> and <c>ticksPerWheel</c> is &lt;= 0</exception>
        public HashedWheelTimer(
            TimeSpan tickInterval,
            int ticksPerWheel,
            long maxPendingTimeouts)
        {
            if (tickInterval <= TimeSpan.Zero)
            {
                throw new ArgumentException($"{nameof(tickInterval)} must be greater than 0: {tickInterval}");
            }
            if (Math.Ceiling(tickInterval.TotalMilliseconds) > int.MaxValue)
            {
                throw new ArgumentException($"{nameof(tickInterval)} must be less than or equal to ${int.MaxValue} ms.");
            }
            if (ticksPerWheel <= 0)
            {
                throw new ArgumentException($"{nameof(ticksPerWheel)} must be greater than 0: {ticksPerWheel}");
            }
            if (ticksPerWheel > int.MaxValue / 2 + 1)
            {
                throw new ArgumentOutOfRangeException(
                          $"{nameof(ticksPerWheel)} may not be greater than 2^30: {ticksPerWheel}");
            }

            // Normalize ticksPerWheel to power of two and initialize the wheel.
            this.wheel  = CreateWheel(ticksPerWheel);
            this.worker = new Worker(this);
            this.mask   = this.wheel.Length - 1;

            this.tickDuration = tickInterval.Ticks;

            // Prevent overflow
            if (this.tickDuration >= long.MaxValue / this.wheel.Length)
            {
                throw new ArgumentException(
                          string.Format(
                              "tickInterval: {0} (expected: 0 < tickInterval in nanos < {1}",
                              tickInterval,
                              long.MaxValue / this.wheel.Length));
            }
            this.workerThread = new XThread(st => this.worker.Run());

            this.maxPendingTimeouts = maxPendingTimeouts;

            if (Interlocked.Increment(ref instanceCounter) > InstanceCountLimit &&
                Interlocked.CompareExchange(ref warnedTooManyInstances, 1, 0) == 0)
            {
                ReportTooManyInstances();
            }
        }
Esempio n. 3
0
        /// <summary>Creates a new timer.</summary>
        /// <param name="tickInterval">the interval between two consecutive ticks</param>
        /// <param name="ticksPerWheel">the size of the wheel</param>
        /// <param name="maxPendingTimeouts">The maximum number of pending timeouts after which call to
        /// <c>newTimeout</c> will result in <see cref="RejectedExecutionException"/> being thrown.
        /// No maximum pending timeouts limit is assumed if this value is 0 or negative.</param>
        /// <exception cref="ArgumentException">if either of <c>tickInterval</c> and <c>ticksPerWheel</c> is &lt;= 0</exception>
        public HashedWheelTimer(TimeSpan tickInterval, int ticksPerWheel, long maxPendingTimeouts)
        {
            if (tickInterval <= TimeSpan.Zero)
            {
                ThrowHelper.ThrowArgumentException_MustBeGreaterThanZero(tickInterval);
            }
            if (Math.Ceiling(tickInterval.TotalMilliseconds) > int.MaxValue)
            {
                ThrowHelper.ThrowArgumentException_MustBeLessThanOrEqualTo();
            }
            if (ticksPerWheel <= 0)
            {
                ThrowHelper.ThrowArgumentException_MustBeGreaterThanZero(ticksPerWheel);
            }
            if (ticksPerWheel > int.MaxValue / 2 + 1)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException_MustBeGreaterThan(ticksPerWheel);
            }

            // Normalize ticksPerWheel to power of two and initialize the wheel.
            _wheel  = CreateWheel(ticksPerWheel);
            _worker = new Worker(this);
            _mask   = _wheel.Length - 1;

            _tickDuration = tickInterval.Ticks;

            // Prevent overflow
            if (_tickDuration >= long.MaxValue / _wheel.Length)
            {
                throw new ArgumentException(
                          string.Format(
                              "tickInterval: {0} (expected: 0 < tickInterval in nanos < {1}",
                              tickInterval,
                              long.MaxValue / _wheel.Length));
            }
            _workerThread = new XThread(st => _worker.Run());

            _maxPendingTimeouts = maxPendingTimeouts;

            if (Interlocked.Increment(ref v_instanceCounter) > InstanceCountLimit &&
                0u >= (uint)Interlocked.CompareExchange(ref v_warnedTooManyInstances, 1, 0))
            {
                ReportTooManyInstances();
            }
        }
Esempio n. 4
0
 void CreateLongRunningTask(XParameterizedThreadStart threadStartFunc)
 {
     this.task = Task.Factory.StartNew(() =>
     {
         // We start the task running, then unleash it by signaling the readyToStart event.
         // This is needed to avoid thread reuse for tasks (see below)
         this.readyToStart.WaitOne();
         // This is the first time we're using this thread, therefore the TLS slot must be empty
         if (tls_this_thread != null)
         {
             Debug.WriteLine("warning: tls_this_thread already created; OS thread reused");
             Debug.Assert(false);
         }
         tls_this_thread = this;
         threadStartFunc(this.startupParameter);
         this.completed.Set();
     },
                                       CancellationToken.None,
                                       TaskCreationOptions.LongRunning,
                                       TaskScheduler.Default);
 }
        public LoopExecutor(IEventLoopGroup parent, string threadName, TimeSpan breakoutInterval) : base(parent)
        {
            this.preciseBreakoutInterval     = (long)breakoutInterval.TotalMilliseconds;
            this.terminationCompletionSource = new TaskCompletionSource();
            this.taskQueue = PlatformDependent.NewMpscQueue <IRunnable>();
            this.scheduler = new ExecutorTaskScheduler(this);

            this.loop        = new Loop();
            this.asyncHandle = new Async(this.loop, OnCallback, this);
            this.timerHandle = new Timer(this.loop, OnCallback, this);
            string name = $"{this.GetType().Name}:{this.loop.Handle}";

            if (!string.IsNullOrEmpty(threadName))
            {
                name = $"{name}({threadName})";
            }
            this.thread = new XThread(Run)
            {
                Name = name
            };
            this.loopRunStart = new ManualResetEventSlim(false, 1);
        }
Esempio n. 6
0
        public LoopExecutor(IEventLoopGroup parent, string threadName, TimeSpan breakoutInterval) : base(parent)
        {
            this.preciseBreakoutInterval = PreciseTimeSpan.FromTimeSpan(breakoutInterval);
            this.preciseTimerInterval    = PreciseTimeSpan.FromTimeSpan(TimeSpan.FromTicks(breakoutInterval.Ticks * 2));

            this.terminationCompletionSource = new TaskCompletionSource();
            this.taskQueue = PlatformDependent.NewMpscQueue <IRunnable>();
            this.scheduler = new ExecutorTaskScheduler(this);

            this.loop        = new Loop();
            this.asyncHandle = new Async(this.loop, RunAllTasksCallback, this);
            this.timerHandle = new Timer(this.loop, RunAllTasksCallback, this);
            string name = string.Format(DefaultWorkerThreadName, this.loop.Handle);

            if (!string.IsNullOrEmpty(threadName))
            {
                name = $"{name} ({threadName})";
            }
            this.thread = new XThread(RunLoop)
            {
                Name = name
            };
        }
Esempio n. 7
0
        public static long Run()
        {
            long      ran        = 0;
            const int Iterations = 100 * 1000 * 1000;

            Thread thread = null;

            thread = new Thread(() =>
            {
                CodeTimer.Time(true, "Thread", Iterations, () =>
                {
                    if (Thread.CurrentThread == thread)
                    {
                        ran++;
                    }
                });
            });
            thread.Start();
            thread.Join(100000);

            XThread xthread = null;

            xthread = new XThread(() =>
            {
                CodeTimer.Time(true, "XThread", Iterations, () =>
                {
                    if (XThread.CurrentThread == xthread)
                    {
                        ran++;
                    }
                });
            });
            xthread.Start();
            xthread.Join(100000);

            return(ran);
        }
Esempio n. 8
0
        void DestroyUp(FABHandlerContext ctx, bool inEventLoop)
        {
            XThread           currentThread = XThread.CurrentThread;
            FABHandlerContext tailContext   = this.tail;

            while (true)
            {
                if (ctx == tailContext)
                {
                    this.DestroyDown(currentThread, tailContext.Prev, inEventLoop);
                    break;
                }

                IEventExecutor executor = ctx.Executor;
                if (!inEventLoop && !executor.IsInEventLoop(currentThread))
                {
                    executor.Execute((self, c) => ((FABChannelPipeline)self).DestroyUp((FABHandlerContext)c, true), this, ctx);
                    break;
                }

                ctx         = ctx.Next;
                inEventLoop = false;
            }
        }
Esempio n. 9
0
 public static void LoopRunDefaultError(this IInternalLogger logger, XThread thread, IntPtr handle, Exception ex)
 {
     logger.Error("Loop {}:{} run default error.", thread.Name, handle, ex);
 }
Esempio n. 10
0
 public static void LoopThreadFinished(this IInternalLogger logger, XThread thread, IntPtr handle)
 {
     logger.Info("Loop {}:{} thread finished.", thread.Name, handle);
 }
Esempio n. 11
0
 public static void LoopReleaseError(this IInternalLogger logger, XThread thread, IntPtr handle, Exception ex)
 {
     logger.Warn("{}:{} release error {}", thread.Name, handle, ex);
 }
Esempio n. 12
0
 public static void LoopDisposed(this IInternalLogger logger, XThread thread, IntPtr handle)
 {
     logger.Info("{}:{} disposed.", thread.Name, handle);
 }
Esempio n. 13
0
 public static void FreedThreadLocalBufferFromThread(this IInternalLogger logger, int numFreed, XThread deathWatchThread)
 {
     logger.Debug("Freed {} thread-local buffer(s) from thread: {}", numFreed, deathWatchThread.Name);
 }
Esempio n. 14
0
 public static void ExecutionLoopFailed(this IInternalLogger logger, XThread thread, Exception ex)
 {
     logger.Error("{}: execution loop failed", thread.Name, ex);
 }
 public override bool IsInEventLoop(XThread thread)
 {
     return(true);
 }
Esempio n. 16
0
 public override bool IsInEventLoop(XThread t) => this.thread == t;