private void ExitExtracted(bool useMemoryBarrier) { if (useMemoryBarrier) { Thread.VolatileWrite(ref _isHeld, 0); ThreadingHelper.VolatileWrite(ref _ownerThread, null); } else { _isHeld = 0; _ownerThread = null; } }
/// <summary> /// This is to be called just before the task does its final state transition. /// It traverses the list of exceptional children, and appends their aggregate exceptions into this one's exception list /// </summary> internal void AddExceptionsFromChildren() { // In rare occurences during AppDomainUnload() processing, it is possible for this method to be called // simultaneously on the same task from two different contexts. This can result in m_exceptionalChildren // being nulled out while it is being processed, which could lead to a NullReferenceException. To // protect ourselves, we'll cache m_exceptionalChildren in a local variable. var tmp = ThreadingHelper.VolatileRead(ref _exceptionalChildren); if (tmp != null) { // This lock is necessary because even though AddExceptionsFromChildren is last to execute, it may still // be racing with the code segment at the bottom of Finish() that prunes the exceptional child array. lock (tmp) { foreach (var task in tmp) { // Ensure any exceptions thrown by children are added to the parent. // In doing this, we are implicitly marking children as being "handled". Contract.Assert(task.IsCompleted, "Expected all tasks in list to be completed"); if (task.IsFaulted && !task.IsExceptionObservedByParent) { var exceptionsHolder = ThreadingHelper.VolatileRead(ref task._exceptionsHolder); if (exceptionsHolder == null) { Contract.Assert(false); } else { // No locking necessary since child task is finished adding exceptions // and concurrent CreateExceptionObject() calls do not constitute // a concurrency hazard. AddException(exceptionsHolder.CreateExceptionObject(false, null)); } } } } // Reduce memory pressure by getting rid of the array ThreadingHelper.VolatileWrite(ref _exceptionalChildren, null); } }
public void ReleaseValueFactory() { ThreadingHelper.VolatileWrite(ref _valueFactory, null); }
public static void Write <T>(ref T location, T value) where T : class { ThreadingHelper.VolatileWrite(ref location, value); }
public void ReleaseAction() { ThreadingHelper.VolatileWrite(ref _action, null); }