public static CancellationTokenSource CreateLinkedTokenSource(CancellationToken token1, CancellationToken token2)
        {
            CancellationTokenSource state = new CancellationTokenSource();

            if (token1.CanBeCanceled)
            {
                state.m_linkingRegistrations = new List <CancellationTokenRegistration>();
                state.m_linkingRegistrations.Add(token1.InternalRegisterWithoutEC(s_LinkedTokenCancelDelegate, state));
            }
            if (token2.CanBeCanceled)
            {
                if (state.m_linkingRegistrations == null)
                {
                    state.m_linkingRegistrations = new List <CancellationTokenRegistration>();
                }
                state.m_linkingRegistrations.Add(token2.InternalRegisterWithoutEC(s_LinkedTokenCancelDelegate, state));
            }
            return(state);
        }
Example #2
0
        public static CancellationTokenSource CreateLinkedTokenSource(CancellationToken token1, CancellationToken token2)
        {
            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            bool canBeCanceled = token2.CanBeCanceled;

            if (token1.CanBeCanceled)
            {
                cancellationTokenSource.m_linkingRegistrations    = new CancellationTokenRegistration[canBeCanceled ? 2 : 1];
                cancellationTokenSource.m_linkingRegistrations[0] = token1.InternalRegisterWithoutEC(CancellationTokenSource.s_LinkedTokenCancelDelegate, (object)cancellationTokenSource);
            }
            if (canBeCanceled)
            {
                int index = 1;
                if (cancellationTokenSource.m_linkingRegistrations == null)
                {
                    cancellationTokenSource.m_linkingRegistrations = new CancellationTokenRegistration[1];
                    index = 0;
                }
                cancellationTokenSource.m_linkingRegistrations[index] = token2.InternalRegisterWithoutEC(CancellationTokenSource.s_LinkedTokenCancelDelegate, (object)cancellationTokenSource);
            }
            return(cancellationTokenSource);
        }
Example #3
0
        /// <summary>
        /// Blocks the current thread until the current <see cref="ManualResetEventSlim"/> is set, using a
        /// 32-bit signed integer to measure the time interval, while observing a <see
        /// cref="T:System.Threading.CancellationToken"/>.
        /// </summary>
        /// <param name="millisecondsTimeout">The number of milliseconds to wait, or <see
        /// cref="Timeout.Infinite"/>(-1) to wait indefinitely.</param>
        /// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken"/> to
        /// observe.</param>
        /// <returns>true if the <see cref="System.Threading.ManualResetEventSlim"/> was set; otherwise,
        /// false.</returns>
        /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="millisecondsTimeout"/> is a
        /// negative number other than -1, which represents an infinite time-out.</exception>
        /// <exception cref="T:System.InvalidOperationException">
        /// The maximum number of waiters has been exceeded.
        /// </exception>
        /// <exception cref="T:System.Threading.OperationCanceledException"><paramref
        /// name="cancellationToken"/> was canceled.</exception>
        public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
        {
            ThrowIfDisposed();
            cancellationToken.ThrowIfCancellationRequested(); // an early convenience check

            if (millisecondsTimeout < -1)
            {
                throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout));
            }

            if (!IsSet)
            {
                if (millisecondsTimeout == 0)
                {
                    // For 0-timeouts, we just return immediately.
                    return(false);
                }


                // We spin briefly before falling back to allocating and/or waiting on a true event.
                uint startTime = 0;
                bool bNeedTimeoutAdjustment  = false;
                int  realMillisecondsTimeout = millisecondsTimeout; //this will be adjusted if necessary.

                if (millisecondsTimeout != Timeout.Infinite)
                {
                    // We will account for time spent spinning, so that we can decrement it from our
                    // timeout.  In most cases the time spent in this section will be negligible.  But
                    // we can't discount the possibility of our thread being switched out for a lengthy
                    // period of time.  The timeout adjustments only take effect when and if we actually
                    // decide to block in the kernel below.

                    startTime = TimeoutHelper.GetTime();
                    bNeedTimeoutAdjustment = true;
                }

                // Spin
                int spinCount = SpinCount;
                var spinner   = new SpinWait();
                while (spinner.Count < spinCount)
                {
                    spinner.SpinOnce(SpinWait.Sleep1ThresholdForSpinBeforeWait);

                    if (IsSet)
                    {
                        return(true);
                    }

                    if (spinner.Count >= 100 && spinner.Count % 10 == 0) // check the cancellation token if the user passed a very large spin count
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                    }
                }

                // Now enter the lock and wait.
                EnsureLockObjectCreated();

                // We must register and deregister the token outside of the lock, to avoid deadlocks.
                using (cancellationToken.InternalRegisterWithoutEC(s_cancellationTokenCallback, this))
                {
                    lock (m_lock)
                    {
                        // Loop to cope with spurious wakeups from other waits being canceled
                        while (!IsSet)
                        {
                            // If our token was canceled, we must throw and exit.
                            cancellationToken.ThrowIfCancellationRequested();

                            //update timeout (delays in wait commencement are due to spinning and/or spurious wakeups from other waits being canceled)
                            if (bNeedTimeoutAdjustment)
                            {
                                realMillisecondsTimeout = TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout);
                                if (realMillisecondsTimeout <= 0)
                                {
                                    return(false);
                                }
                            }

                            // There is a race condition that Set will fail to see that there are waiters as Set does not take the lock,
                            // so after updating waiters, we must check IsSet again.
                            // Also, we must ensure there cannot be any reordering of the assignment to Waiters and the
                            // read from IsSet.  This is guaranteed as Waiters{set;} involves an Interlocked.CompareExchange
                            // operation which provides a full memory barrier.
                            // If we see IsSet=false, then we are guaranteed that Set() will see that we are
                            // waiting and will pulse the monitor correctly.

                            Waiters = Waiters + 1;

                            if (IsSet)     //This check must occur after updating Waiters.
                            {
                                Waiters--; //revert the increment.
                                return(true);
                            }

                            // Now finally perform the wait.
                            try
                            {
                                // ** the actual wait **
                                if (!Monitor.Wait(m_lock, realMillisecondsTimeout))
                                {
                                    return(false); //return immediately if the timeout has expired.
                                }
                            }
                            finally
                            {
                                // Clean up: we're done waiting.
                                Waiters = Waiters - 1;
                            }

                            // Now just loop back around, and the right thing will happen.  Either:
                            //     1. We had a spurious wake-up due to some other wait being canceled via a different cancellationToken (rewait)
                            // or  2. the wait was successful. (the loop will break)
                        }
                    }
                }
            } // automatically disposes (and deregisters) the callback

            return(true); //done. The wait was satisfied.
        }
 public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
 {
     this.ThrowIfDisposed();
     cancellationToken.ThrowIfCancellationRequested();
     if (millisecondsTimeout < -1)
     {
         throw new ArgumentOutOfRangeException("millisecondsTimeout");
     }
     if (!this.IsSet)
     {
         if (millisecondsTimeout == 0)
         {
             return(false);
         }
         uint startTime            = 0;
         bool flag                 = false;
         int  millisecondsTimeout1 = millisecondsTimeout;
         if (millisecondsTimeout != -1)
         {
             startTime = TimeoutHelper.GetTime();
             flag      = true;
         }
         int num1      = 10;
         int num2      = 5;
         int num3      = 20;
         int spinCount = this.SpinCount;
         for (int index = 0; index < spinCount; ++index)
         {
             if (this.IsSet)
             {
                 return(true);
             }
             if (index < num1)
             {
                 if (index == num1 / 2)
                 {
                     Thread.Yield();
                 }
                 else
                 {
                     Thread.SpinWait(PlatformHelper.ProcessorCount * (4 << index));
                 }
             }
             else if (index % num3 == 0)
             {
                 Thread.Sleep(1);
             }
             else if (index % num2 == 0)
             {
                 Thread.Sleep(0);
             }
             else
             {
                 Thread.Yield();
             }
             if (index >= 100 && index % 10 == 0)
             {
                 cancellationToken.ThrowIfCancellationRequested();
             }
         }
         this.EnsureLockObjectCreated();
         using (cancellationToken.InternalRegisterWithoutEC(ManualResetEventSlim.s_cancellationTokenCallback, (object)this))
         {
             lock (this.m_lock)
             {
                 while (!this.IsSet)
                 {
                     cancellationToken.ThrowIfCancellationRequested();
                     if (flag)
                     {
                         millisecondsTimeout1 = TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout);
                         if (millisecondsTimeout1 <= 0)
                         {
                             return(false);
                         }
                     }
                     this.Waiters = this.Waiters + 1;
                     if (this.IsSet)
                     {
                         this.Waiters = this.Waiters - 1;
                         return(true);
                     }
                     try
                     {
                         if (!Monitor.Wait(this.m_lock, millisecondsTimeout1))
                         {
                             return(false);
                         }
                     }
                     finally
                     {
                         this.Waiters = this.Waiters - 1;
                     }
                 }
             }
         }
     }
     return(true);
 }
Example #5
0
        /// <summary>
        /// Blocks the current thread until the current <see cref="ManualResetEventSlim"/> is set, using a
        /// 32-bit signed integer to measure the time interval, while observing a <see
        /// cref="T:System.Threading.CancellationToken"/>.
        /// </summary>
        /// <param name="millisecondsTimeout">The number of milliseconds to wait, or <see
        /// cref="Timeout.Infinite"/>(-1) to wait indefinitely.</param>
        /// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken"/> to
        /// observe.</param>
        /// <returns>true if the <see cref="System.Threading.ManualResetEventSlim"/> was set; otherwise,
        /// false.</returns>
        /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="millisecondsTimeout"/> is a
        /// negative number other than -1, which represents an infinite time-out.</exception>
        /// <exception cref="T:System.InvalidOperationException">
        /// The maximum number of waiters has been exceeded.
        /// </exception>
        /// <exception cref="T:System.Threading.OperationCanceledException"><paramref
        /// name="cancellationToken"/> was canceled.</exception>
        public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
        {
            ThrowIfDisposed();
            cancellationToken.ThrowIfCancellationRequested(); // an early convenience check

            if (millisecondsTimeout < -1)
            {
                throw new ArgumentOutOfRangeException("millisecondsTimeout");
            }

            if (!IsSet)
            {
                if (millisecondsTimeout == 0)
                {
                    // For 0-timeouts, we just return immediately.
                    return false;
                }


                // We spin briefly before falling back to allocating and/or waiting on a true event.
                uint startTime = 0;
                bool bNeedTimeoutAdjustment = false;
                int realMillisecondsTimeout = millisecondsTimeout; //this will be adjusted if necessary.

                if (millisecondsTimeout != Timeout.Infinite)
                {
                    // We will account for time spent spinning, so that we can decrement it from our
                    // timeout.  In most cases the time spent in this section will be negligible.  But
                    // we can't discount the possibility of our thread being switched out for a lengthy
                    // period of time.  The timeout adjustments only take effect when and if we actually
                    // decide to block in the kernel below.

                    startTime = TimeoutHelper.GetTime();
                    bNeedTimeoutAdjustment = true;
                }

                //spin
                int HOW_MANY_SPIN_BEFORE_YIELD = 10;
                int HOW_MANY_YIELD_EVERY_SLEEP_0 = 5;
                int HOW_MANY_YIELD_EVERY_SLEEP_1 = 20;

                int spinCount = SpinCount;
                for (int i = 0; i < spinCount; i++)
                {
                    if (IsSet)
                    {
                        return true;
                    }

                    else if (i < HOW_MANY_SPIN_BEFORE_YIELD)
                    {
                        if (i == HOW_MANY_SPIN_BEFORE_YIELD / 2)
                        {
                            SpinWait.Yield();
                        }
                        else
                        {
                            SpinWait.Spin(PlatformHelper.ProcessorCount * (4 << i));
                        }
                    }
                    else if (i % HOW_MANY_YIELD_EVERY_SLEEP_1 == 0)
                    {
                        Helpers.Sleep(1);
                    }
                    else if (i % HOW_MANY_YIELD_EVERY_SLEEP_0 == 0)
                    {
                        Helpers.Sleep(0);
                    }
                    else
                    {
                        SpinWait.Yield();
                    }

                    if (i >= 100 && i % 10 == 0) // check the cancellation token if the user passed a very large spin count
                        cancellationToken.ThrowIfCancellationRequested();
                }

                // Now enter the lock and wait.
                EnsureLockObjectCreated();

                // We must register and deregister the token outside of the lock, to avoid deadlocks.
                using (cancellationToken.InternalRegisterWithoutEC(s_cancellationTokenCallback, this))
                {
                    lock (m_lock)
                    {
                        // Loop to cope with spurious wakeups from other waits being canceled
                        while (!IsSet)
                        {
                            // If our token was canceled, we must throw and exit.
                            cancellationToken.ThrowIfCancellationRequested();

                            //update timeout (delays in wait commencement are due to spinning and/or spurious wakeups from other waits being canceled)
                            if (bNeedTimeoutAdjustment)
                            {
                                realMillisecondsTimeout = TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout);
                                if (realMillisecondsTimeout <= 0)
                                    return false;
                            }

                            // There is a race that Set will fail to see that there are waiters as Set does not take the lock, 
                            // so after updating waiters, we must check IsSet again.
                            // Also, we must ensure there cannot be any reordering of the assignment to Waiters and the
                            // read from IsSet.  This is guaranteed as Waiters{set;} involves an Interlocked.CompareExchange
                            // operation which provides a full memory barrier.
                            // If we see IsSet=false, then we are guaranteed that Set() will see that we are
                            // waiting and will pulse the monitor correctly.

                            Waiters = Waiters + 1;

                            if (IsSet) //This check must occur after updating Waiters.
                            {
                                Waiters--; //revert the increment.
                                return true;
                            }

                            // Now finally perform the wait.
                            try
                            {
                                // ** the actual wait **
                                if (!m_condition.Wait(realMillisecondsTimeout))
                                    return false; //return immediately if the timeout has expired.
                            }
                            finally
                            {
                                // Clean up: we're done waiting.
                                Waiters = Waiters - 1;
                            }
                            // Now just loop back around, and the right thing will happen.  Either:
                            //     1. We had a spurious wake-up due to some other wait being canceled via a different cancellationToken (rewait)
                            // or  2. the wait was successful. (the loop will break)

                        }
                    }
                }
            } // automatically disposes (and deregisters) the callback 

            return true; //done. The wait was satisfied.
        }
Example #6
0
        /// <summary>
        /// Blocks the current thread until it can enter the <see cref="SemaphoreSlim"/>,
        /// using a 32-bit signed integer to measure the time interval,
        /// while observing a <see cref="T:System.Threading.CancellationToken"/>.
        /// </summary>
        /// <param name="millisecondsTimeout">The number of milliseconds to wait, or <see cref="Timeout.Infinite"/>(-1) to
        /// wait indefinitely.</param>
        /// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken"/> to observe.</param>
        /// <returns>true if the current thread successfully entered the <see cref="SemaphoreSlim"/>; otherwise, false.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="millisecondsTimeout"/> is a negative number other than -1,
        /// which represents an infinite time-out.</exception>
        /// <exception cref="System.OperationCanceledException"><paramref name="cancellationToken"/> was canceled.</exception>
        public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
        {
            CheckDispose();

            // Validate input
            if (millisecondsTimeout < -1)
            {
                throw new ArgumentOutOfRangeException(
                          "totalMilliSeconds", millisecondsTimeout, SR.SemaphoreSlim_Wait_TimeoutWrong);
            }

            cancellationToken.ThrowIfCancellationRequested();

            uint startTime = 0;

            if (millisecondsTimeout != Timeout.Infinite && millisecondsTimeout > 0)
            {
                startTime = TimeoutHelper.GetTime();
            }

            bool        waitSuccessful = false;
            Task <bool> asyncWaitTask  = null;
            bool        lockTaken      = false;

            //Register for cancellation outside of the main lock.
            //NOTE: Register/deregister inside the lock can deadlock as different lock acquisition orders could
            //      occur for (1)this.m_lockObj and (2)cts.internalLock
            CancellationTokenRegistration cancellationTokenRegistration = cancellationToken.InternalRegisterWithoutEC(s_cancellationTokenCanceledEventHandler, this);

            try
            {
                // Perf: first spin wait for the count to be positive, but only up to the first planned yield.
                //       This additional amount of spinwaiting in addition
                //       to Monitor.Enter()’s spinwaiting has shown measurable perf gains in test scenarios.
                //
                SpinWait spin = new SpinWait();
                while (m_currentCount == 0 && !spin.NextSpinWillYield)
                {
                    spin.SpinOnce();
                }
                // entering the lock and incrementing waiters must not suffer a thread-abort, else we cannot
                // clean up m_waitCount correctly, which may lead to deadlock due to non-woken waiters.
                try { }
                finally
                {
                    m_lock.Acquire();
                    lockTaken = true;
                    if (lockTaken)
                    {
                        m_waitCount++;
                    }
                }

                // If there are any async waiters, for fairness we'll get in line behind
                // then by translating our synchronous wait into an asynchronous one that we
                // then block on (once we've released the lock).
                if (m_asyncHead != null)
                {
                    Debug.Assert(m_asyncTail != null, "tail should not be null if head isn't");
                    asyncWaitTask = WaitAsync(millisecondsTimeout, cancellationToken);
                }
                // There are no async waiters, so we can proceed with normal synchronous waiting.
                else
                {
                    // If the count > 0 we are good to move on.
                    // If not, then wait if we were given allowed some wait duration

                    OperationCanceledException oce = null;

                    if (m_currentCount == 0)
                    {
                        if (millisecondsTimeout == 0)
                        {
                            return(false);
                        }

                        // Prepare for the main wait...
                        // wait until the count become greater than zero or the timeout is expired
                        try
                        {
                            waitSuccessful = WaitUntilCountOrTimeout(millisecondsTimeout, startTime, cancellationToken);
                        }
                        catch (OperationCanceledException e) { oce = e; }
                    }

                    // Now try to acquire.  We prioritize acquisition over cancellation/timeout so that we don't
                    // lose any counts when there are asynchronous waiters in the mix.  Asynchronous waiters
                    // defer to synchronous waiters in priority, which means that if it's possible an asynchronous
                    // waiter didn't get released because a synchronous waiter was present, we need to ensure
                    // that synchronous waiter succeeds so that they have a chance to release.
                    Debug.Assert(!waitSuccessful || m_currentCount > 0,
                                 "If the wait was successful, there should be count available.");
                    if (m_currentCount > 0)
                    {
                        waitSuccessful = true;
                        m_currentCount--;
                    }
                    else if (oce != null)
                    {
                        throw oce;
                    }

                    // Exposing wait handle which is lazily initialized if needed
                    if (m_waitHandle != null && m_currentCount == 0)
                    {
                        m_waitHandle.Reset();
                    }
                }
            }
            finally
            {
                // Release the lock
                if (lockTaken)
                {
                    m_waitCount--;
                    m_lock.Release();
                }

                // Unregister the cancellation callback.
                cancellationTokenRegistration.Dispose();
            }

            // If we had to fall back to asynchronous waiting, block on it
            // here now that we've released the lock, and return its
            // result when available.  Otherwise, this was a synchronous
            // wait, and whether we successfully acquired the semaphore is
            // stored in waitSuccessful.

            return((asyncWaitTask != null) ? asyncWaitTask.GetAwaiter().GetResult() : waitSuccessful);
        }
 public static CancellationTokenSource CreateLinkedTokenSource(CancellationToken token1, CancellationToken token2)
 {
     CancellationTokenSource state = new CancellationTokenSource();
     if (token1.CanBeCanceled)
     {
         state.m_linkingRegistrations = new List<CancellationTokenRegistration>();
         state.m_linkingRegistrations.Add(token1.InternalRegisterWithoutEC(s_LinkedTokenCancelDelegate, state));
     }
     if (token2.CanBeCanceled)
     {
         if (state.m_linkingRegistrations == null)
         {
             state.m_linkingRegistrations = new List<CancellationTokenRegistration>();
         }
         state.m_linkingRegistrations.Add(token2.InternalRegisterWithoutEC(s_LinkedTokenCancelDelegate, state));
     }
     return state;
 }
Example #8
0
        public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
        {
            this.CheckDispose();
            if (millisecondsTimeout < -1)
            {
                throw new ArgumentOutOfRangeException("totalMilliSeconds", millisecondsTimeout, SemaphoreSlim.GetResourceString("SemaphoreSlim_Wait_TimeoutWrong"));
            }
            cancellationToken.ThrowIfCancellationRequested();
            uint startTime = 0U;

            if (millisecondsTimeout != -1 && millisecondsTimeout > 0)
            {
                startTime = TimeoutHelper.GetTime();
            }
            bool        result = false;
            Task <bool> task   = null;
            bool        flag   = false;
            CancellationTokenRegistration cancellationTokenRegistration = cancellationToken.InternalRegisterWithoutEC(SemaphoreSlim.s_cancellationTokenCanceledEventHandler, this);

            try
            {
                SpinWait spinWait = default(SpinWait);
                while (this.m_currentCount == 0 && !spinWait.NextSpinWillYield)
                {
                    spinWait.SpinOnce();
                }
                try
                {
                }
                finally
                {
                    Monitor.Enter(this.m_lockObj, ref flag);
                    if (flag)
                    {
                        this.m_waitCount++;
                    }
                }
                if (this.m_asyncHead != null)
                {
                    task = this.WaitAsync(millisecondsTimeout, cancellationToken);
                }
                else
                {
                    OperationCanceledException ex = null;
                    if (this.m_currentCount == 0)
                    {
                        if (millisecondsTimeout == 0)
                        {
                            return(false);
                        }
                        try
                        {
                            result = this.WaitUntilCountOrTimeout(millisecondsTimeout, startTime, cancellationToken);
                        }
                        catch (OperationCanceledException ex2)
                        {
                            ex = ex2;
                        }
                    }
                    if (this.m_currentCount > 0)
                    {
                        result = true;
                        this.m_currentCount--;
                    }
                    else if (ex != null)
                    {
                        throw ex;
                    }
                    if (this.m_waitHandle != null && this.m_currentCount == 0)
                    {
                        this.m_waitHandle.Reset();
                    }
                }
            }
            finally
            {
                if (flag)
                {
                    this.m_waitCount--;
                    Monitor.Exit(this.m_lockObj);
                }
                cancellationTokenRegistration.Dispose();
            }
            if (task == null)
            {
                return(result);
            }
            return(task.GetAwaiter().GetResult());
        }
 public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
 {
     this.ThrowIfDisposed();
     cancellationToken.ThrowIfCancellationRequested();
     if (millisecondsTimeout < -1)
     {
         throw new ArgumentOutOfRangeException("millisecondsTimeout");
     }
     if (!this.IsSet)
     {
         if (millisecondsTimeout == 0)
         {
             return(false);
         }
         uint startTime = 0U;
         bool flag      = false;
         int  num       = millisecondsTimeout;
         if (millisecondsTimeout != -1)
         {
             startTime = TimeoutHelper.GetTime();
             flag      = true;
         }
         int num2      = 10;
         int num3      = 5;
         int num4      = 20;
         int spinCount = this.SpinCount;
         for (int i = 0; i < spinCount; i++)
         {
             if (this.IsSet)
             {
                 return(true);
             }
             if (i < num2)
             {
                 if (i == num2 / 2)
                 {
                     Thread.Yield();
                 }
                 else
                 {
                     Thread.SpinWait(4 << i);
                 }
             }
             else if (i % num4 == 0)
             {
                 Thread.Sleep(1);
             }
             else if (i % num3 == 0)
             {
                 Thread.Sleep(0);
             }
             else
             {
                 Thread.Yield();
             }
             if (i >= 100 && i % 10 == 0)
             {
                 cancellationToken.ThrowIfCancellationRequested();
             }
         }
         this.EnsureLockObjectCreated();
         using (cancellationToken.InternalRegisterWithoutEC(ManualResetEventSlim.s_cancellationTokenCallback, this))
         {
             object @lock = this.m_lock;
             lock (@lock)
             {
                 while (!this.IsSet)
                 {
                     cancellationToken.ThrowIfCancellationRequested();
                     if (flag)
                     {
                         num = TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout);
                         if (num <= 0)
                         {
                             return(false);
                         }
                     }
                     this.Waiters++;
                     if (this.IsSet)
                     {
                         int waiters = this.Waiters;
                         this.Waiters = waiters - 1;
                         return(true);
                     }
                     try
                     {
                         if (!Monitor.Wait(this.m_lock, num))
                         {
                             return(false);
                         }
                     }
                     finally
                     {
                         this.Waiters--;
                     }
                 }
             }
         }
         return(true);
     }
     return(true);
 }
Example #10
0
 public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
 {
     this.ThrowIfDisposed();
     cancellationToken.ThrowIfCancellationRequested();
     if (millisecondsTimeout < -1)
     {
         throw new ArgumentOutOfRangeException("millisecondsTimeout");
     }
     if (!this.IsSet)
     {
         if (millisecondsTimeout == 0)
         {
             return false;
         }
         uint startTime = 0u;
         bool flag = false;
         int num = millisecondsTimeout;
         if (millisecondsTimeout != -1)
         {
             startTime = TimeoutHelper.GetTime();
             flag = true;
         }
         int num2 = 10;
         int num3 = 5;
         int num4 = 20;
         int spinCount = this.SpinCount;
         for (int i = 0; i < spinCount; i++)
         {
             if (this.IsSet)
             {
                 return true;
             }
             if (i < num2)
             {
                 if (i == num2 / 2)
                 {
                     Thread.Sleep(0);
                 }
                 else
                 {
                     Thread.SpinWait(PlatformHelper.ProcessorCount * (4 << i));
                 }
             }
             else
             {
                 if (i % num4 == 0)
                 {
                     Thread.Sleep(1);
                 }
                 else
                 {
                     Thread.Sleep(0);
                     //if (i % num3 == 0)
                     //{
                     //    Thread.Sleep(0);
                     //}
                     //else
                     //{
                     //    Thread.Sleep(0);
                     //}
                 }
             }
             if (i >= 100 && i % 10 == 0)
             {
                 cancellationToken.ThrowIfCancellationRequested();
             }
         }
         this.EnsureLockObjectCreated();
         using (cancellationToken.InternalRegisterWithoutEC(ManualResetEventSlim.s_cancellationTokenCallback, this))
         {
             lock (this.m_lock)
             {
                 while (!this.IsSet)
                 {
                     cancellationToken.ThrowIfCancellationRequested();
                     if (flag)
                     {
                         num = TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout);
                         if (num <= 0)
                         {
                             bool result = false;
                             return result;
                         }
                     }
                     this.Waiters++;
                     if (this.IsSet)
                     {
                         this.Waiters--;
                         bool result = true;
                         return result;
                     }
                     try
                     {
                         if (!Monitor.Wait(this.m_lock, num))
                         {
                             bool result = false;
                             return result;
                         }
                     }
                     finally
                     {
                         this.Waiters--;
                     }
                 }
             }
         }
         return true;
     }
     return true;
 }
Example #11
0
 public static CancellationTokenSource CreateLinkedTokenSource(CancellationToken token1, CancellationToken token2)
 {
     CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
     bool canBeCanceled = token2.CanBeCanceled;
     if (token1.CanBeCanceled)
     {
         cancellationTokenSource.m_linkingRegistrations = new CancellationTokenRegistration[canBeCanceled ? 2 : 1];
         cancellationTokenSource.m_linkingRegistrations[0] = token1.InternalRegisterWithoutEC(CancellationTokenSource.s_LinkedTokenCancelDelegate, cancellationTokenSource);
     }
     if (canBeCanceled)
     {
         int num = 1;
         if (cancellationTokenSource.m_linkingRegistrations == null)
         {
             cancellationTokenSource.m_linkingRegistrations = new CancellationTokenRegistration[1];
             num = 0;
         }
         cancellationTokenSource.m_linkingRegistrations[num] = token2.InternalRegisterWithoutEC(CancellationTokenSource.s_LinkedTokenCancelDelegate, cancellationTokenSource);
     }
     return cancellationTokenSource;
 }
 /// <summary>
 /// Creates the linked token source.
 /// </summary>
 /// <param name="token1">The token1.</param>
 /// <param name="token2">The token2.</param>
 /// <returns></returns>
 public static CancellationTokenSource CreateLinkedTokenSource(CancellationToken token1, CancellationToken token2)
 {
     var state = new CancellationTokenSource();
     var canBeCanceled = token2.CanBeCanceled;
     if (token1.CanBeCanceled)
     {
         state._linkingRegistrations = new CancellationTokenRegistration[canBeCanceled ? 2 : 1];
         state._linkingRegistrations[0] = token1.InternalRegisterWithoutEC(_LinkedTokenCancelDelegate, state);
     }
     if (canBeCanceled)
     {
         var index = 1;
         if (state._linkingRegistrations == null)
         {
             state._linkingRegistrations = new CancellationTokenRegistration[1];
             index = 0;
         }
         state._linkingRegistrations[index] = token2.InternalRegisterWithoutEC(_LinkedTokenCancelDelegate, state);
     }
     return state;
 }