public void ThrowIfCancellationRequested() { if (this.IsCancellationRequested) { throw new OperationCanceledException2(Environment2.GetResourceString("OperationCanceled"), null); } }
/// <summary> /// Increments the <see cref="T:System.Threading.CountdownEvent"/>'s current count by a specified /// value. /// </summary> /// <param name="signalCount">The value by which to increase <see cref="CurrentCount"/>.</param> /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="signalCount"/> is less than /// 0.</exception> /// <exception cref="T:System.InvalidOperationException">The current instance is already /// set.</exception> /// <exception cref="T:System.InvalidOperationException"><see cref="CurrentCount"/> is equal to <see /// cref="T:System.Int32.MaxValue"/>.</exception> /// <exception cref="T:System.ObjectDisposedException">The current instance has already been /// disposed.</exception> public void AddCount(int signalCount) { if (!TryAddCount(signalCount)) { throw new InvalidOperationException(Environment2.GetResourceString("CountdownEvent_Increment_AlreadyZero")); } }
/// <summary> /// Throw ObjectDisposedException if the MRES is disposed /// </summary> private void ThrowIfDisposed() { if ((m_combinedState & Dispose_BitMask) != 0) { throw new ObjectDisposedException(Environment2.GetResourceString("ManualResetEventSlim_Disposed")); } }
/// <summary> /// Transitions the underlying /// <see cref="T:System.Threading.Tasks.Task{TResult}"/> into the /// <see cref="System.Threading.Tasks.TaskStatus.Faulted">Faulted</see> /// state. /// </summary> /// <param name="exceptions">The collection of exceptions to bind to this <see /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</param> /// <exception cref="T:System.ArgumentNullException">The <paramref name="exceptions"/> argument is null.</exception> /// <exception cref="T:System.ArgumentException">There are one or more null elements in <paramref name="exceptions"/>.</exception> /// <exception cref="T:System.InvalidOperationException"> /// The underlying <see cref="T:System.Threading.Tasks.Task{TResult}"/> is already in one /// of the three final states: /// <see cref="System.Threading.Tasks.TaskStatus.RanToCompletion">RanToCompletion</see>, /// <see cref="System.Threading.Tasks.TaskStatus.Faulted">Faulted</see>, or /// <see cref="System.Threading.Tasks.TaskStatus.Canceled">Canceled</see>. /// </exception> /// <exception cref="T:System.ObjectDisposedException">The <see cref="Task"/> was disposed.</exception> public void SetException(IEnumerable <Exception> exceptions) { if (!TrySetException(exceptions)) { throw new InvalidOperationException(Environment2.GetResourceString("TaskT_TransitionToFinal_AlreadyCompleted")); } }
// Throw an ODE if this CancellationToken's source is disposed. internal void ThrowIfSourceDisposed() { if ((m_source != null) && m_source.IsDisposed) { throw new ObjectDisposedException(null, Environment2.GetResourceString("CancellationToken_SourceDisposed")); } }
/// <summary> /// Transitions the underlying /// <see cref="T:System.Threading.Tasks.Task{TResult}"/> into the /// <see cref="System.Threading.Tasks.TaskStatus.Canceled">Canceled</see> /// state. /// </summary> /// <exception cref="T:System.InvalidOperationException"> /// The underlying <see cref="T:System.Threading.Tasks.Task{TResult}"/> is already in one /// of the three final states: /// <see cref="System.Threading.Tasks.TaskStatus.RanToCompletion">RanToCompletion</see>, /// <see cref="System.Threading.Tasks.TaskStatus.Faulted">Faulted</see>, or /// <see cref="System.Threading.Tasks.TaskStatus.Canceled">Canceled</see>. /// </exception> /// <exception cref="T:System.ObjectDisposedException">The <see cref="Task"/> was disposed.</exception> public void SetCanceled() { if (!TrySetCanceled()) { throw new InvalidOperationException(Environment2.GetResourceString("TaskT_TransitionToFinal_AlreadyCompleted")); } }
// -- Internal methods. /// <summary> /// Throws an exception if the source has been disposed. /// </summary> internal void ThrowIfDisposed() { if (m_disposed) { throw new ObjectDisposedException(null, Environment2.GetResourceString("CancellationTokenSource_Disposed")); } }
/// <summary> /// Creates a <see cref="T:System.Threading.CancellationTokenSource">CancellationTokenSource</see> that will be in the canceled state /// when any of the source tokens are in the canceled state. /// </summary> /// <param name="tokens">The <see cref="T:System.Threading.CancellationToken">CancellationToken</see> instances to observe.</param> /// <returns>A <see cref="T:System.Threading.CancellationTokenSource">CancellationTokenSource</see> that is linked /// to the source tokens.</returns> /// <exception cref="T:System.ArgumentNullException"><paramref name="tokens"/> is null.</exception> /// <exception cref="T:System.ObjectDisposedException">A <see /// cref="T:System.Threading.CancellationTokenSource">CancellationTokenSource</see> associated with /// one of the source tokens has been disposed.</exception> public static CancellationTokenSource CreateLinkedTokenSource(params CancellationToken[] tokens) { if (tokens == null) { throw new ArgumentNullException("tokens"); } if (tokens.Length == 0) { throw new ArgumentException(Environment2.GetResourceString("CancellationToken_CreateLinkedToken_TokensIsEmpty")); } // a defensive copy is not required as the array has value-items that have only a single IntPtr field, // hence each item cannot be null itself, and reads of the payloads cannot be torn. Contract.EndContractBlock(); CancellationTokenSource linkedTokenSource = new CancellationTokenSource(); linkedTokenSource.m_linkingRegistrations = new List <CancellationTokenRegistration>(); for (int i = 0; i < tokens.Length; i++) { if (tokens[i].CanBeCanceled) { linkedTokenSource.m_linkingRegistrations.Add(tokens[i].InternalRegisterWithoutEC(s_LinkedTokenCancelDelegate, linkedTokenSource)); } } return(linkedTokenSource); }
/// <summary> /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskCanceledException"/> class /// with a reference to the <see cref="T:System.Threading.Tasks.Task"/> that has been canceled. /// </summary> /// <param name="task">A task that has been canceled.</param> public TaskCanceledException(Task task) : #if PFX_LEGACY_3_5 // since in this case the class is derived from the 3.5 OCE, we can't pass down the task's CT in the base ctor base(Environment2.GetResourceString("TaskCanceledException_ctor_DefaultMessage")) #else base(Environment2.GetResourceString("TaskCanceledException_ctor_DefaultMessage"), task != null ? task.CancellationToken : new CancellationToken())
/// <summary> /// ContinueTryEnter for the thread tracking mode enabled /// </summary> private void ContinueTryEnterWithThreadTracking(int millisecondsTimeout, long startTicks, ref bool lockTaken) { Contract.Assert(IsThreadOwnerTrackingEnabled); int lockUnowned = 0; // We are using thread IDs to mark ownership. Snap the thread ID and check for recursion. // We also must or the ID enablement bit, to ensure we propagate when we CAS it in. int m_newOwner = Thread.CurrentThread.ManagedThreadId; if (m_owner == m_newOwner) { // We don't allow lock recursion. throw new LockRecursionException(Environment2.GetResourceString("SpinLock_TryEnter_LockRecursionException")); } SpinWait spinner = new SpinWait(); // Loop until the lock has been successfully acquired or, if specified, the timeout expires. do { // We failed to get the lock, either from the fast route or the last iteration // and the timeout hasn't expired; spin once and try again. spinner.SpinOnce(); // Test before trying to CAS, to avoid acquiring the line exclusively unnecessarily. if (m_owner == lockUnowned) { #if !FEATURE_CORECLR Thread.BeginCriticalRegion(); #endif #if PFX_LEGACY_3_5 if (Interlocked.CompareExchange(ref m_owner, m_newOwner, lockUnowned) == lockUnowned) { lockTaken = true; return; } #else if (Interlocked.CompareExchange(ref m_owner, m_newOwner, lockUnowned, ref lockTaken) == lockUnowned) { return; } #endif #if !FEATURE_CORECLR // The thread failed to get the lock, so we don't need to remain in a critical region. Thread.EndCriticalRegion(); #endif } // Check the timeout. We only RDTSC if the next spin will yield, to amortize the cost. if (millisecondsTimeout == 0 || (millisecondsTimeout != Timeout.Infinite && spinner.NextSpinWillYield && TimeoutExpired(startTicks, millisecondsTimeout))) { return; } } while (true); }
public IEnumerator <KeyValuePair <long, TSource> > GetEnumerator() { if (this.m_disposed) { throw new ObjectDisposedException(Environment2.GetResourceString("PartitionerStatic_CanNotCallGetEnumeratorAfterSourceHasBeenDisposed")); } return(new Partitioner.DynamicPartitionerForIEnumerable <TSource> .InternalPartitionEnumerator(this.m_sharedReader, this.m_sharedIndex, this.m_hasNoElementsLeft, this.m_sharedLock, this.m_activePartitionCount, this, this.m_maxChunkSize)); }
/// <summary> /// Attempts to acquire the lock in a reliable manner, such that even if an exception occurs within /// the method call, <paramref name="lockTaken"/> can be examined reliably to determine whether the /// lock was acquired. /// </summary> /// <remarks> /// Unlike <see cref="Enter"/>, TryEnter will not block indefinitely waiting for the lock to be /// available. It will block until either the lock is available or until the <paramref /// name="millisecondsTimeout"/> has expired. /// </remarks> /// <param name="millisecondsTimeout">The number of milliseconds to wait, or <see /// cref="System.Threading.Timeout.Infinite"/> (-1) to wait indefinitely.</param> /// <param name="lockTaken">True if the lock is acquired; otherwise, false. <paramref /// name="lockTaken"/> must be initialized to false prior to calling this method.</param> /// <exception cref="T:System.Threading.LockRecursionException"> /// Thread ownership tracking is enabled, and the current thread has already acquired this lock. /// </exception> /// <exception cref="T:System.ArgumentException"> /// The <paramref name="lockTaken"/> argument must be initialized to false prior to calling TryEnter. /// </exception> /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="millisecondsTimeout"/> is /// a negative number other than -1, which represents an infinite time-out.</exception> public void TryEnter(int millisecondsTimeout, ref bool lockTaken) { // validate input if (lockTaken) { lockTaken = false; throw new System.ArgumentException(Environment2.GetResourceString("SpinLock_TryReliableEnter_ArgumentException")); } if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException( "millisecondsTimeout", millisecondsTimeout, Environment2.GetResourceString("SpinLock_TryEnter_ArgumentOutOfRange")); } // Fast path to acquire the lock if the lock is released // If the thread tracking enabled set the new owner to the current thread id // Id not, set the anonymous bit lock int observedOwner = m_owner; int newOwner = 0; if (IsThreadOwnerTrackingEnabled) { if (observedOwner == LOCK_UNOWNED) { newOwner = Thread.CurrentThread.ManagedThreadId; } } else if ((observedOwner & LOCK_ANONYMOUS_OWNED) == LOCK_UNOWNED) { newOwner = observedOwner | LOCK_ANONYMOUS_OWNED; } if (newOwner != 0) { #if !FEATURE_CORECLR Thread.BeginCriticalRegion(); #endif #if PFX_LEGACY_3_5 if (Interlocked.CompareExchange(ref m_owner, newOwner, observedOwner) == observedOwner) { lockTaken = true; return; } #else if (Interlocked.CompareExchange(ref m_owner, newOwner, observedOwner, ref lockTaken) == observedOwner) { return; } #endif #if !FEATURE_CORECLR Thread.EndCriticalRegion(); #endif } // Fast path failed, try slow path ContinueTryEnter(millisecondsTimeout, ref lockTaken); }
/// <summary> /// Throws a <see cref="T:System.OperationCanceledException">OperationCanceledException</see> if /// this token has had cancellation requested. /// </summary> /// <remarks> /// This method provides functionality equivalent to: /// <code> /// if (token.IsCancellationRequested) /// throw new OperationCanceledException(token); /// </code> /// </remarks> /// <exception cref="System.OperationCanceledException">The token has had cancellation requested.</exception> /// <exception cref="T:System.ObjectDisposedException">The associated <see /// cref="T:System.Threading.CancellationTokenSource">CancellationTokenSource</see> has been disposed.</exception> public void ThrowIfCancellationRequested() { if (IsCancellationRequested) #if PFX_LEGACY_3_5 { throw new OperationCanceledException2(Environment2.GetResourceString("OperationCanceled"), this); } #else { throw new OperationCanceledException(Environment2.GetResourceString("OperationCanceled"), this); } #endif }
protected bool TryExecuteTask(Task task) { if (task.ExecutingTaskScheduler != this) { throw new InvalidOperationException(Environment2.GetResourceString("TaskScheduler_ExecuteTask_WrongTaskScheduler")); } return(task.ExecuteEntry(true)); }
internal void Stop() { // disallow setting of PLS_STOPPED bit only if PLS_BROKEN was already set if (!AtomicLoopStateUpdate(PLS_STOPPED, PLS_BROKEN)) { throw new InvalidOperationException( Environment2.GetResourceString("ParallelState_Stop_InvalidOperationException_StopAfterBreak")); } }
private static T EnsureInitializedCore <T>(ref T target, Func <T> valueFactory) where T : class { T t = valueFactory(); if (t == null) { throw new InvalidOperationException(Environment2.GetResourceString("Lazy_StaticInit_InvalidOperation")); } Interlocked.CompareExchange <T>(ref target, t, default(T)); return(target); }
private static T ActivatorFactorySelector() { try { return((T)Activator.CreateInstance(typeof(T))); } catch (MissingMethodException) { throw new MissingMemberException(Environment2.GetResourceString("Lazy_CreateValue_NoParameterlessCtorForT")); } }
/// <summary> /// Constructs a SynchronizationContextTaskScheduler associated with <see cref="T:System.Threading.SynchronizationContext.Current"/> /// </summary> /// <exception cref="T:System.InvalidOperationException">This constructor expects <see cref="T:System.Threading.SynchronizationContext.Current"/> to be set.</exception> internal SynchronizationContextTaskScheduler() { SynchronizationContext synContext = SynchronizationContext.Current; // make sure we have a synccontext to work with if (synContext == null) { throw new InvalidOperationException(Environment2.GetResourceString("TaskScheduler_FromCurrentSynchronizationContext_NoCurrent")); } m_synchronizationContext = synContext; }
/// <summary> /// Transitions the underlying /// <see cref="T:System.Threading.Tasks.Task{TResult}"/> into the /// <see cref="System.Threading.Tasks.TaskStatus.Faulted">Faulted</see> /// state. /// </summary> /// <param name="exception">The exception to bind to this <see /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</param> /// <exception cref="T:System.ArgumentNullException">The <paramref name="exception"/> argument is null.</exception> /// <exception cref="T:System.InvalidOperationException"> /// The underlying <see cref="T:System.Threading.Tasks.Task{TResult}"/> is already in one /// of the three final states: /// <see cref="System.Threading.Tasks.TaskStatus.RanToCompletion">RanToCompletion</see>, /// <see cref="System.Threading.Tasks.TaskStatus.Faulted">Faulted</see>, or /// <see cref="System.Threading.Tasks.TaskStatus.Canceled">Canceled</see>. /// </exception> /// <exception cref="T:System.ObjectDisposedException">The <see cref="Task"/> was disposed.</exception> public void SetException(Exception exception) { if (exception == null) { throw new ArgumentNullException("exception"); } if (!TrySetException(exception)) { throw new InvalidOperationException(Environment2.GetResourceString("TaskT_TransitionToFinal_AlreadyCompleted")); } }
/// <summary> /// Initializes a new instance of the <see cref="T:System.Threading.SpinLock"/> /// structure with the option to track thread IDs to improve debugging. /// </summary> /// <remarks> /// The default constructor for <see cref="SpinLock"/> tracks thread ownership. /// </remarks> /// <summary> /// Acquires the lock in a reliable manner, such that even if an exception occurs within the method /// call, <paramref name="lockTaken"/> can be examined reliably to determine whether the lock was /// acquired. /// </summary> /// <remarks> /// <see cref="SpinLock"/> is a non-reentrant lock, meaning that if a thread holds the lock, it is /// not allowed to enter the lock again. If thread ownership tracking is enabled (whether it's /// enabled is available through <see cref="IsThreadOwnerTrackingEnabled"/>), an exception will be /// thrown when a thread tries to re-enter a lock it already holds. However, if thread ownership /// tracking is disabled, attempting to enter a lock already held will result in deadlock. /// </remarks> /// <param name="lockTaken">True if the lock is acquired; otherwise, false. <paramref /// name="lockTaken"/> must be initialized to false prior to calling this method.</param> /// <exception cref="T:System.Threading.LockRecursionException"> /// Thread ownership tracking is enabled, and the current thread has already acquired this lock. /// </exception> /// <exception cref="T:System.ArgumentException"> /// The <paramref name="lockTaken"/> argument must be initialized to false prior to calling Enter. /// </exception> public void Enter(ref bool lockTaken) { if (lockTaken) { lockTaken = false; throw new System.ArgumentException(Environment2.GetResourceString("SpinLock_TryReliableEnter_ArgumentException")); } // Fast path to acquire the lock if the lock is released // If the thread tracking enabled set the new owner to the current thread id // Id not, set the anonymous bit lock int observedOwner = m_owner; int newOwner = 0; bool threadTrackingEnabled = (m_owner & LOCK_ID_DISABLE_MASK) == 0; if (threadTrackingEnabled) { if (observedOwner == LOCK_UNOWNED) { newOwner = Thread.CurrentThread.ManagedThreadId; } } else if ((observedOwner & LOCK_ANONYMOUS_OWNED) == LOCK_UNOWNED) { newOwner = observedOwner | LOCK_ANONYMOUS_OWNED; // set the lock bit } if (newOwner != 0) { #if !FEATURE_CORECLR Thread.BeginCriticalRegion(); #endif #if PFX_LEGACY_3_5 if (Interlocked.CompareExchange(ref m_owner, newOwner, observedOwner) == observedOwner) { lockTaken = true; return; } #else if (Interlocked.CompareExchange(ref m_owner, newOwner, observedOwner, ref lockTaken) == observedOwner) { // Fast path succeeded return; } #endif #if !FEATURE_CORECLR Thread.EndCriticalRegion(); #endif } //Fast path failed, try slow path ContinueTryEnter(Timeout.Infinite, ref lockTaken); }
/// <summary> /// Initialize the target using the given delegate (slow path). /// </summary> /// <typeparam name="T">The reference type of the reference to be initialized.</typeparam> /// <param name="target">The variable that need to be initialized</param> /// <param name="valueFactory">The delegate that will be executed to initialize the target</param> /// <returns>The initialized variable</returns> private static T EnsureInitializedCore <T>(ref T target, Func <T> valueFactory) where T : class { T value = valueFactory(); if (value == null) { throw new InvalidOperationException(Environment2.GetResourceString("Lazy_StaticInit_InvalidOperation")); } Interlocked.CompareExchange(ref target, value, null); Contract.Assert(target != null); return(target); }
/// <summary> /// Attempts to acquire the lock in a reliable manner, such that even if an exception occurs within /// the method call, <paramref name="lockTaken"/> can be examined reliably to determine whether the /// lock was acquired. /// </summary> /// <remarks> /// Unlike <see cref="Enter"/>, TryEnter will not block indefinitely waiting for the lock to be /// available. It will block until either the lock is available or until the <paramref /// name="timeout"/> /// has expired. /// </remarks> /// <param name="timeout">A <see cref="System.TimeSpan"/> that represents the number of milliseconds /// to wait, or a <see cref="System.TimeSpan"/> that represents -1 milliseconds to wait indefinitely. /// </param> /// <param name="lockTaken">True if the lock is acquired; otherwise, false. <paramref /// name="lockTaken"/> must be initialized to false prior to calling this method.</param> /// <exception cref="T:System.Threading.LockRecursionException"> /// Thread ownership tracking is enabled, and the current thread has already acquired this lock. /// </exception> /// <exception cref="T:System.ArgumentException"> /// The <paramref name="lockTaken"/> argument must be initialized to false prior to calling TryEnter. /// </exception> /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="timeout"/> is a negative /// number other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater /// than <see cref="System.Int32.MaxValue"/> milliseconds. /// </exception> public void TryEnter(TimeSpan timeout, ref bool lockTaken) { // Validate the timeout Int64 totalMilliseconds = (Int64)timeout.TotalMilliseconds; if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { throw new System.ArgumentOutOfRangeException( "timeout", timeout, Environment2.GetResourceString("SpinLock_TryEnter_ArgumentOutOfRange")); } // Call reliable enter with the int-based timeout milliseconds TryEnter((int)timeout.TotalMilliseconds, ref lockTaken); }
/// <summary> /// Spins until the specified condition is satisfied or until the specified timeout is expired. /// </summary> /// <param name="condition">A delegate to be executed over and over until it returns true.</param> /// <param name="timeout"> /// A <see cref="TimeSpan"/> that represents the number of milliseconds to wait, /// or a TimeSpan that represents -1 milliseconds to wait indefinitely.</param> /// <returns>True if the condition is satisfied within the timeout; otherwise, false</returns> /// <exception cref="ArgumentNullException">The <paramref name="condition"/> argument is null.</exception> /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="timeout"/> is a negative number /// other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater than /// <see cref="System.Int32.MaxValue"/>.</exception> public static bool SpinUntil(Func <bool> condition, TimeSpan timeout) { // Validate the timeout Int64 totalMilliseconds = (Int64)timeout.TotalMilliseconds; if (totalMilliseconds < -1 || totalMilliseconds > Int32.MaxValue) { throw new System.ArgumentOutOfRangeException( "timeout", timeout, Environment2.GetResourceString("SpinWait_SpinUntil_TimeoutWrong")); } // Call wait with the timeout milliseconds return(SpinUntil(condition, (int)timeout.TotalMilliseconds)); }
/// <summary> /// Private helper function to lazily create the value using the calueSelector if specified in the constructor or the default parameterless constructor /// </summary> /// <returns>Returns the boxed object</returns> private Boxed CreateValue() { Boxed boxed = new Boxed(); boxed.m_ownerHolder = m_holder; boxed.Value = m_valueFactory == null ? default(T) : m_valueFactory(); if (m_holder.Boxed != null && m_holder.Boxed.m_ownerHolder == m_holder) { throw new InvalidOperationException(Environment2.GetResourceString("ThreadLocal_Value_RecursiveCallsToValue")); } m_holder.Boxed = boxed; return(boxed); }
/// <summary> /// Add an exception to the internal list. This will ensure the holder is /// in the proper state (handled/unhandled) depending on the list's contents. /// </summary> /// <param name="exceptionObject">An exception object (either an Exception or an /// IEnumerable{Exception}) to add to the list.</param> internal void Add(object exceptionObject) { Contract.Assert(exceptionObject != null); Contract.Assert(m_exceptions != null); Contract.Assert(exceptionObject is Exception || exceptionObject is IEnumerable <Exception>, "TaskExceptionHolder.Add(): Expected Exception or IEnumerable<Exception>"); Exception exception = exceptionObject as Exception; if (exception != null) { m_exceptions.Add(exception); } else { IEnumerable <Exception> exColl = exceptionObject as IEnumerable <Exception>; if (exColl != null) { m_exceptions.AddRange(exColl); } else { throw new ArgumentException(Environment2.GetResourceString("TaskExceptionHolder_UnknownExceptionType"), "exceptionObject"); } } // If all of the exceptions are ThreadAbortExceptions and/or // AppDomainUnloadExceptions, we do not want the finalization // probe to propagate them, so we consider the holder to be // handled. If a subsequent exception comes in of a different // kind, we will reactivate the holder. for (int i = 0; i < m_exceptions.Count; i++) { if (m_exceptions[i].GetType() != typeof(ThreadAbortException) && m_exceptions[i].GetType() != typeof(AppDomainUnloadedException)) { MarkAsUnhandled(); break; } else if (i == m_exceptions.Count - 1) { MarkAsHandled(false); } } }
/// <summary> /// Registers multiple signals with the <see cref="T:System.Threading.CountdownEvent"/>, /// decrementing its count by the specified amount. /// </summary> /// <param name="signalCount">The number of signals to register.</param> /// <returns>true if the signals caused the count to reach zero and the event was set; otherwise, /// false.</returns> /// <exception cref="T:System.InvalidOperationException"> /// The current instance is already set. -or- Or <paramref name="signalCount"/> is greater than <see /// cref="CurrentCount"/>. /// </exception> /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="signalCount"/> is less /// than 1.</exception> /// <exception cref="T:System.ObjectDisposedException">The current instance has already been /// disposed.</exception> public bool Signal(int signalCount) { if (signalCount <= 0) { throw new ArgumentOutOfRangeException("signalCount"); } ThrowIfDisposed(); Contract.Assert(m_event != null); int observedCount; SpinWait spin = new SpinWait(); while (true) { observedCount = m_currentCount; // If the latch is already signaled, we will fail. if (observedCount < signalCount) { throw new InvalidOperationException(Environment2.GetResourceString("CountdownEvent_Decrement_BelowZero")); } // This disables the "CS0420: a reference to a volatile field will not be treated as volatile" warning // for this statement. This warning is clearly senseless for Interlocked operations. #pragma warning disable 0420 if (Interlocked.CompareExchange(ref m_currentCount, observedCount - signalCount, observedCount) == observedCount) #pragma warning restore 0420 { break; } // The CAS failed. Spin briefly and try again. spin.SpinOnce(); } // If we were the last to signal, set the event. if (observedCount == signalCount) { m_event.Set(); return(true); } Contract.Assert(m_currentCount >= 0, "latch was decremented below zero"); return(false); }
/// <summary> /// Initializes a new instance of the <see cref="ManualResetEventSlim"/> /// class with a Boolen value indicating whether to set the intial state to signaled and a specified /// spin count. /// </summary> /// <param name="initialState">true to set the initial state to signaled; false to set the initial state /// to nonsignaled.</param> /// <param name="spinCount">The number of spin waits that will occur before falling back to a true /// wait.</param> /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="spinCount"/> is less than /// 0 or greater than the maximum allowed value.</exception> public ManualResetEventSlim(bool initialState, int spinCount) { if (spinCount < 0) { throw new ArgumentOutOfRangeException("spinCount"); } if (spinCount > SpinCountState_MaxValue) { throw new ArgumentOutOfRangeException( "spinCount", String.Format(Environment2.GetResourceString("ManualResetEventSlim_ctor_SpinCountOutOfRange"), SpinCountState_MaxValue)); } // We will suppress default spin because the user specified a count. Initialize(initialState, spinCount); }
internal bool TryRunInline(Task task, bool taskWasPreviouslyQueued, object threadStatics) { // Do not inline unstarted tasks (i.e., task.ExecutingTaskScheduler == null). // Do not inline TaskCompletionSource-style (a.k.a. "promise") tasks. // No need to attempt inlining if the task body was already run (i.e. either TASK_STATE_DELEGATE_INVOKED or TASK_STATE_CANCELED bits set) TaskScheduler ets = task.ExecutingTaskScheduler; // Delegate cross-scheduler inlining requests to target scheduler if (ets != this && ets != null) { return(ets.TryRunInline(task, taskWasPreviouslyQueued)); } if ((ets == null) || (task.m_action == null) || task.IsDelegateInvoked || task.IsCanceled || Task.CurrentStackGuard.TryBeginInliningScope() == false) { return(false); } // Task class will still call into TaskScheduler.TryRunInline rather than TryExecuteTaskInline() so that // 1) we can adjust the return code from TryExecuteTaskInline in case a buggy custom scheduler lies to us // 2) we maintain a mechanism for the TLS lookup optimization that we used to have for the ConcRT scheduler (will potentially introduce the same for TP) bool bInlined = false; try { bInlined = TryExecuteTaskInline(task, taskWasPreviouslyQueued); } finally { Task.CurrentStackGuard.EndInliningScope(); } // If the custom scheduler returned true, we should either have the TASK_STATE_DELEGATE_INVOKED or TASK_STATE_CANCELED bit set // Otherwise the scheduler is buggy if (bInlined && !(task.IsDelegateInvoked || task.IsCanceled)) { throw new InvalidOperationException(Environment2.GetResourceString("TaskScheduler_InconsistentStateAfterTryExecuteTaskInline")); } return(bInlined); }
// Helper method to avoid repeating Break() logic between ParallelState64 and ParallelState64<TLocal> internal static void Break(long iteration, ParallelLoopStateFlags64 pflags) { int oldValue = ParallelLoopStateFlags.PLS_NONE; // Attempt to change state from "not stopped or broken or canceled or exceptional" to "broken". if (!pflags.AtomicLoopStateUpdate(ParallelLoopStateFlags.PLS_BROKEN, ParallelLoopStateFlags.PLS_STOPPED | ParallelLoopStateFlags.PLS_EXCEPTIONAL | ParallelLoopStateFlags.PLS_CANCELED, ref oldValue)) { // If we were already stopped, we have a problem if ((oldValue & ParallelLoopStateFlags.PLS_STOPPED) != 0) { throw new InvalidOperationException( Environment2.GetResourceString("ParallelState_Break_InvalidOperationException_BreakAfterStop")); } else { // Apparently we previously got cancelled or became exceptional. No action necessary return; } } // replace shared LowestBreakIteration with CurrentIteration, but only if CurrentIteration // is less than LowestBreakIteration. long oldLBI = pflags.LowestBreakIteration; if (iteration < oldLBI) { SpinWait wait = new SpinWait(); while (Interlocked.CompareExchange( ref pflags.m_lowestBreakIteration, iteration, oldLBI) != oldLBI) { wait.SpinOnce(); oldLBI = pflags.LowestBreakIteration; if (iteration > oldLBI) { break; } } } }
/// <summary> /// Attempts to increment the <see cref="T:System.Threading.CountdownEvent"/>'s current count by a /// specified value. /// </summary> /// <param name="signalCount">The value by which to increase <see cref="CurrentCount"/>.</param> /// <returns>true if the increment succeeded; otherwise, false. If <see cref="CurrentCount"/> is /// already at zero this will return false.</returns> /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="signalCount"/> is less /// than 0.</exception> /// <exception cref="T:System.InvalidOperationException">The current instance is already /// set.</exception> /// <exception cref="T:System.InvalidOperationException"><see cref="CurrentCount"/> is equal to <see /// cref="T:System.Int32.MaxValue"/>.</exception> /// <exception cref="T:System.ObjectDisposedException">The current instance has already been /// disposed.</exception> public bool TryAddCount(int signalCount) { if (signalCount <= 0) { throw new ArgumentOutOfRangeException("signalCount"); } ThrowIfDisposed(); // Loop around until we successfully increment the count. int observedCount; SpinWait spin = new SpinWait(); while (true) { observedCount = m_currentCount; if (observedCount == 0) { return(false); } else if (observedCount > (Int32.MaxValue - signalCount)) { throw new InvalidOperationException(Environment2.GetResourceString("CountdownEvent_Increment_AlreadyMax")); } // This disables the "CS0420: a reference to a volatile field will not be treated as volatile" warning // for this statement. This warning is clearly senseless for Interlocked operations. #pragma warning disable 0420 if (Interlocked.CompareExchange(ref m_currentCount, observedCount + signalCount, observedCount) == observedCount) #pragma warning restore 0420 { break; } // The CAS failed. Spin briefly and try again. spin.SpinOnce(); } return(true); }