Exemple #1
0
            public bool UpdateTimer(IOThreadTimer timer, long dueTime)
            {
                int index = timer.index;

                IOThreadTimer[] timers = this.timers;
                int             count  = this.count;

                Fx.Assert(index > 0, "");
                Fx.Assert(index <= count, "");

                int parentIndex = index / 2;

                if (parentIndex == 0 ||
                    timers[parentIndex].dueTime <= dueTime)
                {
                    int leftChildIndex = index * 2;
                    if (leftChildIndex > count ||
                        timers[leftChildIndex].dueTime >= dueTime)
                    {
                        int rightChildIndex = leftChildIndex + 1;
                        if (rightChildIndex > count ||
                            timers[rightChildIndex].dueTime >= dueTime)
                        {
                            timer.dueTime = dueTime;
                            return(index == 1);
                        }
                    }
                }

                DeleteTimer(timer);
                InsertTimer(timer, dueTime);
                return(true);
            }
Exemple #2
0
            public void DeleteTimer(IOThreadTimer timer)
            {
                int index = timer.index;

                Fx.Assert(index > 0, "");
                Fx.Assert(index <= count, "");

                IOThreadTimer[] timers = this.timers;

                for (; ;)
                {
                    int parentIndex = index / 2;

                    if (parentIndex >= 1)
                    {
                        IOThreadTimer parentTimer = timers[parentIndex];
                        timers[index]     = parentTimer;
                        parentTimer.index = index;
                    }
                    else
                    {
                        break;
                    }

                    index = parentIndex;
                }

                timer.index   = 0;
                timer.dueTime = 0;
                timers[1]     = null;
                DeleteMinTimerCore();
            }
Exemple #3
0
            public void DeleteMinTimer()
            {
                IOThreadTimer minTimer = MinTimer;

                DeleteMinTimerCore();
                minTimer.index   = 0;
                minTimer.dueTime = 0;
            }
Exemple #4
0
            void UpdateWaitableTimer(TimerGroup timerGroup)
            {
                WaitableTimer waitableTimer = timerGroup.WaitableTimer;
                IOThreadTimer minTimer      = timerGroup.TimerQueue.MinTimer;
                long          timeDiff      = waitableTimer.DueTime - minTimer.dueTime;

                if (timeDiff < 0)
                {
                    timeDiff = -timeDiff;
                }
                if (timeDiff > minTimer.maxSkew)
                {
                    waitableTimer.Set(minTimer.dueTime);
                }
            }
Exemple #5
0
            public bool InsertTimer(IOThreadTimer timer, long dueTime)
            {
                Fx.Assert(timer.index == 0, "Timer should not have an index.");

                IOThreadTimer[] timers = this.timers;

                int index = count + 1;

                if (index == timers.Length)
                {
                    timers = new IOThreadTimer[timers.Length * 2];
                    Array.Copy(this.timers, timers, this.timers.Length);
                    this.timers = timers;
                }

                count = index;

                if (index > 1)
                {
                    for (; ;)
                    {
                        int parentIndex = index / 2;

                        if (parentIndex == 0)
                        {
                            break;
                        }

                        IOThreadTimer parent = timers[parentIndex];

                        if (parent.dueTime > dueTime)
                        {
                            timers[index] = parent;
                            parent.index  = index;
                            index         = parentIndex;
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                timers[index] = timer;
                timer.index   = index;
                timer.dueTime = dueTime;
                return(index == 1);
            }
Exemple #6
0
        public void WaitAndBackoff(Action <object> callback, object state)
        {
            if (_backoffCallback != callback || _backoffState != state)
            {
                if (_backoffTimer != null)
                {
                    _backoffTimer.Cancel();
                }
                _backoffCallback = callback;
                _backoffState    = state;
                _backoffTimer    = new IOThreadTimer(callback, state, false, s_maxSkewMilliseconds);
            }

            TimeSpan backoffTime = WaitTimeWithDrift();

            Backoff();
            _backoffTimer.Set(backoffTime);
        }
Exemple #7
0
            void ScheduleElapsedTimers(TimerGroup timerGroup, long now)
            {
                TimerQueue timerQueue = timerGroup.TimerQueue;

                while (timerQueue.Count > 0)
                {
                    IOThreadTimer timer    = timerQueue.MinTimer;
                    long          timeDiff = timer.dueTime - now;
                    if (timeDiff <= timer.maxSkew)
                    {
                        timerQueue.DeleteMinTimer();
                        ActionItem.Schedule(timer.callback, timer.callbackState);
                    }
                    else
                    {
                        break;
                    }
                }
            }
Exemple #8
0
            public bool Cancel(IOThreadTimer timer)
            {
                lock (ThisLock)
                {
                    if (timer.index > 0)
                    {
                        TimerGroup timerGroup = timer.timerGroup;
                        TimerQueue timerQueue = timerGroup.TimerQueue;

                        timerQueue.DeleteTimer(timer);

                        if (timerQueue.Count > 0)
                        {
                            UpdateWaitableTimer(timerGroup);
                        }
                        else
                        {
                            TimerGroup otherTimerGroup = GetOtherTimerGroup(timerGroup);
                            if (otherTimerGroup.TimerQueue.Count == 0)
                            {
                                long now = Ticks.Now;
                                long thisGroupRemainingTime  = timerGroup.WaitableTimer.DueTime - now;
                                long otherGroupRemainingTime = otherTimerGroup.WaitableTimer.DueTime - now;
                                if (thisGroupRemainingTime > maxTimeToWaitForMoreTimers &&
                                    otherGroupRemainingTime > maxTimeToWaitForMoreTimers)
                                {
                                    timerGroup.WaitableTimer.Set(Ticks.Add(now, maxTimeToWaitForMoreTimers));
                                }
                            }
                        }

                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }
            }
Exemple #9
0
            public void Set(IOThreadTimer timer, long dueTime)
            {
                long timeDiff = dueTime - timer.dueTime;

                if (timeDiff < 0)
                {
                    timeDiff = -timeDiff;
                }

                if (timeDiff > timer.maxSkew)
                {
                    lock (ThisLock)
                    {
                        TimerGroup timerGroup = timer.timerGroup;
                        TimerQueue timerQueue = timerGroup.TimerQueue;

                        if (timer.index > 0)
                        {
                            if (timerQueue.UpdateTimer(timer, dueTime))
                            {
                                UpdateWaitableTimer(timerGroup);
                            }
                        }
                        else
                        {
                            if (timerQueue.InsertTimer(timer, dueTime))
                            {
                                UpdateWaitableTimer(timerGroup);

                                if (timerQueue.Count == 1)
                                {
                                    EnsureWaitScheduled();
                                }
                            }
                        }
                    }
                }
            }
Exemple #10
0
            void DeleteMinTimerCore()
            {
                int count = this.count;

                if (count == 1)
                {
                    this.count = 0;
                    timers[1]  = null;
                }
                else
                {
                    IOThreadTimer[] timers    = this.timers;
                    IOThreadTimer   lastTimer = timers[count];
                    this.count = --count;

                    int index = 1;
                    for (; ;)
                    {
                        int leftChildIndex = index * 2;

                        if (leftChildIndex > count)
                        {
                            break;
                        }

                        int           childIndex;
                        IOThreadTimer child;

                        if (leftChildIndex < count)
                        {
                            IOThreadTimer leftChild       = timers[leftChildIndex];
                            int           rightChildIndex = leftChildIndex + 1;
                            IOThreadTimer rightChild      = timers[rightChildIndex];

                            if (rightChild.dueTime < leftChild.dueTime)
                            {
                                child      = rightChild;
                                childIndex = rightChildIndex;
                            }
                            else
                            {
                                child      = leftChild;
                                childIndex = leftChildIndex;
                            }
                        }
                        else
                        {
                            childIndex = leftChildIndex;
                            child      = timers[childIndex];
                        }

                        if (lastTimer.dueTime > child.dueTime)
                        {
                            timers[index] = child;
                            child.index   = index;
                        }
                        else
                        {
                            break;
                        }

                        index = childIndex;

                        if (leftChildIndex >= count)
                        {
                            break;
                        }
                    }

                    timers[index]     = lastTimer;
                    lastTimer.index   = index;
                    timers[count + 1] = null;
                }
            }