protected bool TryComplete(bool didCompleteSynchronously, Exception exception) { lock (this.ThisLock) { if (this.isCompleted) { return(false); } this.exception = exception; this.isCompleted = true; } #if DEBUG this.marker.AsyncResult = null; this.marker = null; #endif this.completedSynchronously = didCompleteSynchronously; if (this.OnCompleting != null) { // Allow exception replacement, like a catch/throw pattern. try { this.OnCompleting(this, this.exception); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } this.exception = e; } } if (didCompleteSynchronously) { // If we completedSynchronously, then there's no chance that the manualResetEvent was created so // we don't need to worry about a race Fx.Assert(this.manualResetEvent == null, "No ManualResetEvent should be created for a synchronous AsyncResult."); } else { lock (this.ThisLock) { if (this.manualResetEvent != null) { this.manualResetEvent.Set(); } } } if (this.callback != null) { try { if (this.VirtualCallback != null) { this.VirtualCallback(this.callback, this); } else { this.callback(this); } } #pragma warning disable 1634 #pragma warning suppress 56500 // transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) { throw; } throw Fx.Exception.AsError(new CallbackException(CommonResources.AsyncCallbackThrewException, e)); } #pragma warning restore 1634 } return(true); }
public TransactionSignalScope(AsyncResult result, Transaction transaction) { Fx.Assert(transaction != null, "Null Transaction provided to AsyncResult.TransactionSignalScope."); this.parent = result; this.transactionScope = Fx.CreateTransactionScope(transaction); }
void CompletionCallback(out Action <object> callback, out object state) { int slot = this.headTail; int slotLowPri; while (true) { Fx.Assert(Bits.Count(slot) != -1, "CompletionCallback called on idle IOTS!"); bool wasEmpty = Bits.Count(slot) == 0; if (wasEmpty) { // We're about to set this to idle. First check the low-priority queue. This alone doesn't // guarantee we service all the low-pri items - there hasn't even been an Interlocked yet. But // we take care of that later. slotLowPri = this.headTailLowPri; while (Bits.CountNoIdle(slotLowPri) != 0) { if (slotLowPri == (slotLowPri = Interlocked.CompareExchange(ref this.headTailLowPri, Bits.IncrementLo(slotLowPri), slotLowPri))) { this.overlapped.Post(this); this.slotsLowPri[slotLowPri & SlotMaskLowPri].DequeueWorkItem(out callback, out state); return; } } } if (slot == (slot = Interlocked.CompareExchange(ref this.headTail, Bits.IncrementLo(slot), slot))) { if (!wasEmpty) { this.overlapped.Post(this); this.slots[slot & SlotMask].DequeueWorkItem(out callback, out state); return; } // We just set the IOThreadScheduler to idle. Check if a low-priority item got added in the // interim. // Interlocked calls create a thread barrier, so this read will give us the value of // headTailLowPri at the time of the interlocked that set us to idle, or later. The invariant // here is that either the low-priority queue was empty at some point after we set the IOTS to // idle (so that the next enqueue will notice, and issue a Post), or that the IOTS was unidle at // some point after we set it to idle (so that the next attempt to go idle will verify that the // low-priority queue is empty). slotLowPri = this.headTailLowPri; if (Bits.CountNoIdle(slotLowPri) != 0) { // Whoops, go back from being idle (unless someone else already did). If we go back, start // over. (We still owe a Post.) slot = Bits.IncrementLo(slot); if (slot == Interlocked.CompareExchange(ref this.headTail, slot + Bits.HiOne, slot)) { slot += Bits.HiOne; continue; } // We know that there's a low-priority work item. But we also know that the IOThreadScheduler // wasn't idle. It's best to let it take care of itself, since according to this method, we // just set the IOThreadScheduler to idle so shouldn't take on any tasks. } break; } } callback = null; state = null; return; }
public void DebugVerifyEmpty() { Fx.Assert(this.gate == 0, "Finalized with unfinished slot."); Fx.Assert(this.heldCallback == null, "Finalized with leaked callback."); Fx.Assert(this.heldState == null, "Finalized with leaked state."); }
void IdleTimerCallback() { Fx.Assert(this.referenceCount == 0, "Cached IotHubConnection's ref count should be zero when idle timeout occurs!"); this.cache.RemoveHubScopeConnectionPool(this.ConnectionString); this.Connection.CloseAsync().Fork(); }
public static void Fork(this Task thisTask, string tracingInfo) { Fx.Assert(thisTask != null, "task is required!"); thisTask.ContinueWith(t => Fx.Exception.TraceHandled(t.Exception, tracingInfo), TaskContinuationOptions.OnlyOnFaulted); }
void SetDeadline() { Fx.Assert(!deadlineSet, "TimeoutHelper deadline set twice."); this.deadline = DateTime.UtcNow + this.originalTimeout; this.deadlineSet = true; }
public static Exception AssertAndThrowFatal(string description) { Fx.Assert(description); throw Fx.Exception.AsError(new FatalException(description)); }
public static Exception AssertAndThrow(string description) { Fx.Assert(description); throw Fx.Exception.AsError(new AssertionFailedException(description)); }