internal void Enqueue(ReceiveScopeSignalGate receiveScope) { // This should only be called from EnsurePump which itself should only be // BeginTryReceive. This makes sure that we don't need locks to enqueue an item. Fx.AssertAndThrow(this.count < this.size, "Cannot Enqueue into a full queue."); this.items[(this.head + this.count) % this.size] = receiveScope; count++; }
private static void OnInnerReceiveCompleted(IAsyncResult nestedResult) { if (!nestedResult.CompletedSynchronously) { ReceiveScopeSignalGate asyncState = nestedResult.AsyncState as ReceiveScopeSignalGate; asyncState.Binder.HandleReceiveAndSignalCompletion(nestedResult, false); } }
static void OnInnerReceiveCompleted(IAsyncResult nestedResult) { if (nestedResult.CompletedSynchronously) { return; } ReceiveScopeSignalGate thisPtr = nestedResult.AsyncState as ReceiveScopeSignalGate; thisPtr.Binder.HandleReceiveAndSignalCompletion(nestedResult, false); }
public bool TrySignal(ReceiveScopeSignalGate scope, IAsyncResult nestedResult) { // Ordered receives can only signal the gate that the AsyncResult owns. // If the head has already been unlocked then it can proceed. if (scope.Signal(nestedResult)) { Dequeue(); return(true); } return(false); }
private void EnsurePump(TimeSpan timeout) { while (!this.pendingResults.IsFull) { ReceiveScopeSignalGate receiveScope = new ReceiveScopeSignalGate(this); this.pendingResults.Enqueue(receiveScope); IAsyncResult nestedResult = this.channelBinder.BeginTryReceive(timeout, onInnerReceiveCompleted, receiveScope); if (nestedResult.CompletedSynchronously) { this.SignalReceiveCompleted(nestedResult); } } }
void EnsurePump(TimeSpan timeout) { // ensure we're running at full throttle, the BeginTryReceive calls we make below on the // IChannelBinder will typically complete future calls to BeginTryReceive made by CannelHandler // corollary to that is that most times these calls will be completed sycnhronously while (!this.pendingResults.IsFull) { ReceiveScopeSignalGate receiveScope = new ReceiveScopeSignalGate(this); // Enqueue the result without locks since this is the pump. // BeginTryReceive can be called only from one thread and // the head is not yet unlocked so no items can proceed. this.pendingResults.Enqueue(receiveScope); IAsyncResult result = this.channelBinder.BeginTryReceive(timeout, onInnerReceiveCompleted, receiveScope); if (result.CompletedSynchronously) { this.SignalReceiveCompleted(result); } } }