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); }
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(); }
public void DeleteMinTimer() { IOThreadTimer minTimer = MinTimer; DeleteMinTimerCore(); minTimer.index = 0; minTimer.dueTime = 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); } }
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); }
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); }
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; } } }
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); } } }
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(); } } } } } }
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; } }