void AfterRunningAllTasks()
        {
            if (this.IsShuttingDown)
            {
                // Immediate shutdown
                this.WakeUp(true);
                return;
            }

            long nextTimeout = DefaultBreakoutTime;

            if (!this.taskQueue.IsEmpty)
            {
                this.timerHandle.Start(nextTimeout, 0);
            }
            else
            {
                IScheduledRunnable nextScheduledTask = this.ScheduledTaskQueue.Peek();
                if (nextScheduledTask != null)
                {
                    PreciseTimeSpan wakeUpTimeout = nextScheduledTask.Deadline - PreciseTimeSpan.FromStart;
                    if (wakeUpTimeout.Ticks > 0)
                    {
                        nextTimeout = (long)wakeUpTimeout.ToTimeSpan().TotalMilliseconds;
                    }
                    this.timerHandle.Start(nextTimeout, 0);
                }
            }
        }
        IRunnable PollTask()
        {
            Contract.Assert(this.InEventLoop);

            IRunnable task = this.taskQueue.Dequeue();

            if (task == null)
            {
                this.emptyEvent.Reset();
                if ((task = this.taskQueue.Dequeue()) == null) // revisit queue as producer might have put a task in meanwhile
                {
                    IScheduledRunnable nextScheduledTask = this.ScheduledTaskQueue.Peek();
                    if (nextScheduledTask != null)
                    {
                        PreciseTimeSpan wakeupTimeout = nextScheduledTask.Deadline - PreciseTimeSpan.FromStart;
                        if (wakeupTimeout.Ticks > 0)
                        {
                            if (this.emptyEvent.Wait(wakeupTimeout.ToTimeSpan()))
                            {
                                // woken up before the next scheduled task was due
                                task = this.taskQueue.Dequeue();
                            }
                        }
                    }
                    else
                    {
                        this.emptyEvent.Wait();
                        task = this.taskQueue.Dequeue();
                    }
                }
            }

            return(task);
        }
Beispiel #3
0
        IRunnable PollTask()
        {
            Contract.Assert(this.InEventLoop);

            IRunnable task;

            if (!this.taskQueue.TryDequeue(out task))
            {
                this.emptyEvent.Reset();
                if (!this.taskQueue.TryDequeue(out task) && !this.IsShuttingDown) // revisit queue as producer might have put a task in meanwhile
                {
                    IScheduledRunnable nextScheduledTask = this.ScheduledTaskQueue.Peek();
                    if (nextScheduledTask != null)
                    {
                        PreciseTimeSpan wakeupTimeout = nextScheduledTask.Deadline - PreciseTimeSpan.FromStart;
                        if (wakeupTimeout.Ticks > 0)
                        {
                            double timeout = wakeupTimeout.ToTimeSpan().TotalMilliseconds;
                            this.emptyEvent.Wait((int)Math.Min(timeout, int.MaxValue - 1));
                        }
                    }
                    else
                    {
                        this.emptyEvent.Wait();
                        this.taskQueue.TryDequeue(out task);
                    }
                }
            }

            return(task);
        }
Beispiel #4
0
        private IRunnable PollTask()
        {
            Debug.Assert(InEventLoop);

            if (!_taskQueue.TryDequeue(out IRunnable task))
            {
                _emptyEvent.Reset();
                if (!_taskQueue.TryDequeue(out task) && !IsShuttingDown) // revisit queue as producer might have put a task in meanwhile
                {
                    if (ScheduledTaskQueue.TryPeek(out IScheduledRunnable nextScheduledTask))
                    {
                        PreciseTimeSpan wakeupTimeout = nextScheduledTask.Deadline - PreciseTimeSpan.FromStart;
                        if (wakeupTimeout.Ticks > 0L) // 此处不要 ulong 转换
                        {
                            double timeout = wakeupTimeout.ToTimeSpan().TotalMilliseconds;
                            _ = _emptyEvent.Wait((int)Math.Min(timeout, int.MaxValue - 1));
                        }
                    }
                    else
                    {
                        _emptyEvent.Wait();
                        _ = _taskQueue.TryDequeue(out task);
                    }
                }
            }

            return(task);
        }
Beispiel #5
0
        private void AfterRunningAllTasks()
        {
            if (IsShuttingDown)
            {
                // Immediate shutdown
                WakeUp(true);
                return;
            }

            long nextTimeout = DefaultBreakoutTime;

            if (_taskQueue.NonEmpty)
            {
                _ = _timerHandle.Start(nextTimeout, 0);
            }
            else
            {
                if (ScheduledTaskQueue.TryPeek(out IScheduledRunnable nextScheduledTask))
                {
                    PreciseTimeSpan wakeUpTimeout = nextScheduledTask.Deadline - PreciseTimeSpan.FromStart;
                    if ((ulong)wakeUpTimeout.Ticks > 0UL)
                    {
                        nextTimeout = (long)wakeUpTimeout.ToTimeSpan().TotalMilliseconds;
                    }
                    _ = _timerHandle.Start(nextTimeout, 0);
                }
            }
        }
        public void Register(PreciseTimeSpan startTimestamp)
        {
            PreciseTimeSpan elapsed   = PreciseTimeSpan.FromStart - startTimestamp;
            long            elapsedMs = (long)elapsed.ToTimeSpan().TotalMilliseconds;

            this.countCounter.IncrementBy(elapsedMs);
            this.baseCounter.Increment();
        }
        public void TestScheduling()
        {
            var  ch     = new EmbeddedChannel(new ChannelHandlerAdapter());
            var  latch  = new CountdownEvent(2);
            Task future = ch.EventLoop.ScheduleAsync(() => latch.Signal(), TimeSpan.FromSeconds(1));

            future.ContinueWith(t => latch.Signal());
            PreciseTimeSpan next = ch.RunScheduledPendingTasks();

            Assert.True(next > PreciseTimeSpan.Zero);
            // Sleep for the nanoseconds but also give extra 50ms as the clock my not be very precise and so fail the test
            // otherwise.
            Thread.Sleep(next.ToTimeSpan() + TimeSpan.FromMilliseconds(50));
            Assert.Equal(PreciseTimeSpan.MinusOne, ch.RunScheduledPendingTasks());
            latch.Wait();
        }
Beispiel #8
0
        public override bool WaitTermination(TimeSpan timeout)
        {
            PreciseTimeSpan deadline = PreciseTimeSpan.Deadline(timeout);

            for (int i = 0; i < _eventLoops.Length; i++)
            {
                var executor = _eventLoops[i];
                for (; ;)
                {
                    PreciseTimeSpan timeLeft = deadline - PreciseTimeSpan.FromStart;
                    if (timeLeft <= PreciseTimeSpan.Zero)
                    {
                        goto LoopEnd;
                    }

                    if (executor.WaitTermination(timeLeft.ToTimeSpan()))
                    {
                        break;
                    }
                }
            }
LoopEnd:
            return(IsTerminated);
        }