void IOCallback(uint errorCode, uint numBytes, NativeOverlapped *nativeOverlappedCallback) { IOThreadScheduler iots = this.scheduler; this.scheduler = null; Action <object> callback; object state; try { } finally { iots.CompletionCallback(out callback, out state); } bool found = true; while (found) { if (callback != null) { callback(state); } try { } finally { found = iots.TryCoalesce(out callback, out state); } } }
bool ScheduleCallbackHelper(Action <object> callback, object state) { int slot = Interlocked.Add(ref this.headTail, Bits.HiOne); bool wasIdle = Bits.Count(slot) == 0; if (wasIdle) { slot = Interlocked.Add(ref this.headTail, Bits.HiOne); } if (Bits.Count(slot) == -1) { throw new InvalidOperationException("Head/Tail overflow!"); } bool wrapped; bool queued = this.slots[slot >> Bits.HiShift & SlotMask].TryEnqueueWorkItem(callback, state, out wrapped); if (wrapped) { IOThreadScheduler next = new IOThreadScheduler(Math.Min(this.slots.Length * 2, MaximumCapacity), this.slotsLowPri.Length); Interlocked.CompareExchange(ref IOThreadScheduler.current, next, this); } if (wasIdle) { this.overlapped.Post(this); } return(queued); }
public void Dispatch() { IQueueReader reader = null; Item item = new Item(); IQueueReader[] outstandingReaders = null; IQueueWaiter[] waiters; bool itemAvailable; lock (ThisLock) { itemAvailable = !((queueState == QueueState.Closed) || (queueState == QueueState.Shutdown)); this.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 = new Action <object>(CompleteOutstandingReadersCallback); } IOThreadScheduler.ScheduleCallbackNoFlow(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 = new Action <object>(OnInvokeDequeuedCallback); } IOThreadScheduler.ScheduleCallbackNoFlow(onInvokeDequeuedCallback, dequeuedCallback); } }
static 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(); IOThreadScheduler.ScheduleCallbackNoFlow(timer.callback, timer.callbackState); } else { break; } } }
bool ScheduleCallbackLowPriHelper(Action <object> callback, object state) { int slot = Interlocked.Add(ref this.headTailLowPri, Bits.HiOne); bool wasIdle = false; if (Bits.CountNoIdle(slot) == 1) { int ht = this.headTail; if (Bits.Count(ht) == -1) { int interlockedResult = Interlocked.CompareExchange(ref this.headTail, ht + Bits.HiOne, ht); if (ht == interlockedResult) { wasIdle = true; } } } if (Bits.CountNoIdle(slot) == 0) { throw new InvalidOperationException("Low-priority Head/Tail overflow!"); } bool wrapped; bool queued = this.slotsLowPri[slot >> Bits.HiShift & SlotMaskLowPri].TryEnqueueWorkItem( callback, state, out wrapped); if (wrapped) { IOThreadScheduler next = new IOThreadScheduler(this.slots.Length, Math.Min(this.slotsLowPri.Length * 2, MaximumCapacity)); Interlocked.CompareExchange(ref IOThreadScheduler.current, next, this); } if (wasIdle) { this.overlapped.Post(this); } return(queued); }
static void CompleteWaitersLater(bool itemAvailable, IQueueWaiter[] waiters) { if (itemAvailable) { if (completeWaitersTrueCallback == null) { completeWaitersTrueCallback = new Action <object>(CompleteWaitersTrueCallback); } IOThreadScheduler.ScheduleCallbackNoFlow(completeWaitersTrueCallback, waiters); } else { if (completeWaitersFalseCallback == null) { completeWaitersFalseCallback = new Action <object>(CompleteWaitersFalseCallback); } IOThreadScheduler.ScheduleCallbackNoFlow(completeWaitersFalseCallback, waiters); } }
public void Signal() { //this.result = !isAborted; IOThreadScheduler.ScheduleCallbackNoFlow(state => ((AsyncWaiter)state).Complete(false), this); }
void ScheduleWait() { IOThreadScheduler.ScheduleCallbackNoFlow(this.onWaitCallback, null); this.waitScheduled = true; }
public void Post(IOThreadScheduler iots) { this.scheduler = iots; ThreadPool.UnsafeQueueNativeOverlapped(this.nativeOverlapped); }
void EnqueueAndDispatch(Item item, bool canDispatchOnThisThread) { bool disposeItem = false; IQueueReader reader = null; bool dispatchLater = false; IQueueWaiter[] waiters; bool itemAvailable; lock (ThisLock) { itemAvailable = !((queueState == QueueState.Closed) || (queueState == QueueState.Shutdown)); this.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 = new Action <object>(OnDispatchCallback); } IOThreadScheduler.ScheduleCallbackNoFlow(onDispatchCallback, this); } else if (disposeItem) { InvokeDequeuedCallback(item.DequeuedCallback); DisposeItem(item); } }
public void Signal() { IOThreadScheduler.ScheduleCallbackNoFlow(s => ((AsyncWaiter)(s)).Complete(false), this); }