public void Dispatch() { IQueueReader reader = null; Item item = new Item(); IQueueReader[] outstandingReaders = null; IQueueWaiter[] waiters = null; bool itemAvailable = true; lock (ThisLock) { itemAvailable = !((queueState == QueueState.Closed) || (queueState == QueueState.Shutdown)); GetWaiters(out waiters); if (queueState != QueueState.Closed) { itemQueue.MakePendingItemAvailable(); if (readerQueue.Count > 0) { item = itemQueue.DequeueAvailableItem(); reader = readerQueue.Dequeue(); if (queueState == QueueState.Shutdown && readerQueue.Count > 0 && itemQueue.ItemCount == 0) { outstandingReaders = new IQueueReader[readerQueue.Count]; readerQueue.CopyTo(outstandingReaders, 0); readerQueue.Clear(); itemAvailable = false; } } } } if (outstandingReaders != null) { if (completeOutstandingReadersCallback == null) { completeOutstandingReadersCallback = CompleteOutstandingReadersCallback; } ActionItem.Schedule(completeOutstandingReadersCallback, outstandingReaders); } if (waiters != null) { CompleteWaitersLater(itemAvailable, waiters); } if (reader != null) { InvokeDequeuedCallback(item.DequeuedCallback); reader.Set(item); } }
static void InvokeDequeuedCallbackLater(Action dequeuedCallback) { if (dequeuedCallback != null) { if (onInvokeDequeuedCallback == null) { onInvokeDequeuedCallback = OnInvokeDequeuedCallback; } ActionItem.Schedule(onInvokeDequeuedCallback, dequeuedCallback); } }
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; } } }
internal void OnTimer() { _timerFiredCallback(_timerFiredState); lock (_cancellationTokenSources) { _timerFired = true; } // Once _timerFired is set, there's no need to hold the lock as // no more will be added to the list. foreach (CancellationTokenSource cts in _cancellationTokenSources) { // TODO: ActionItem.Schedule might be overkill here as I don't expect there // to be many cancellations. There's just no if (!cts.IsCancellationRequested) { ActionItem.Schedule(CancelTokenSource, cts); } } }
static void CompleteWaitersLater(bool itemAvailable, IQueueWaiter[] waiters) { if (itemAvailable) { if (completeWaitersTrueCallback == null) { completeWaitersTrueCallback = CompleteWaitersTrueCallback; } ActionItem.Schedule(completeWaitersTrueCallback, waiters); } else { if (completeWaitersFalseCallback == null) { completeWaitersFalseCallback = CompleteWaitersFalseCallback; } ActionItem.Schedule(completeWaitersFalseCallback, waiters); } }
void ScheduleWait() { ActionItem.Schedule(onWaitCallback, null); waitScheduled = true; }
private void ScheduleWait() { ActionItem.Schedule(_onWaitCallback, null); _waitScheduled = true; }
void EnqueueAndDispatch(Item item, bool canDispatchOnThisThread) { bool disposeItem = false; IQueueReader reader = null; bool dispatchLater = false; IQueueWaiter[] waiters = null; bool itemAvailable = true; lock (ThisLock) { itemAvailable = !((queueState == QueueState.Closed) || (queueState == QueueState.Shutdown)); GetWaiters(out waiters); if (queueState == QueueState.Open) { if (canDispatchOnThisThread) { if (readerQueue.Count == 0) { itemQueue.EnqueueAvailableItem(item); } else { reader = readerQueue.Dequeue(); } } else { if (readerQueue.Count == 0) { itemQueue.EnqueueAvailableItem(item); } else { itemQueue.EnqueuePendingItem(item); dispatchLater = true; } } } else // queueState == QueueState.Closed || queueState == QueueState.Shutdown { disposeItem = true; } } if (waiters != null) { if (canDispatchOnThisThread) { CompleteWaiters(itemAvailable, waiters); } else { CompleteWaitersLater(itemAvailable, waiters); } } if (reader != null) { InvokeDequeuedCallback(item.DequeuedCallback); reader.Set(item); } if (dispatchLater) { if (onDispatchCallback == null) { onDispatchCallback = OnDispatchCallback; } ActionItem.Schedule(onDispatchCallback, this); } else if (disposeItem) { InvokeDequeuedCallback(item.DequeuedCallback); DisposeItem(item); } }