Exemple #1
0
 public void Dispose()
 {
     if (!_disposed)
     {
         _spinLock.Release();
         _disposed = true;
     }
 }
Exemple #2
0
        /// <summary>
        /// Acquires the lock in exclusive mode, blocking
        /// if necessary.
        /// </summary>
        /// <remarks>
        /// Exclusive acquires are given precedence over shared
        /// acquires.
        /// </remarks>
        public void AcquireExclusive()
        {
            int value;
            int i = 0;

#if ENABLE_STATISTICS
            Interlocked.Increment(ref _acqExclCount);
#endif
            while (true)
            {
                value = _value;

                // Try to obtain the lock.
                if ((value & LockOwned) == 0)
                {
#if RIGOROUS_CHECKS
                    System.Diagnostics.Trace.Assert(((value >> LockSharedOwnersShift) & LockSharedOwnersMask) == 0);
#endif
                    if (Interlocked.CompareExchange(
                            ref _value,
                            value + LockOwned,
                            value
                            ) == value)
                    {
                        break;
                    }
                }
                else if (i >= _spinCount)
                {
                    // We need to wait.
                    WaitBlock waitBlock;

                    waitBlock.Flags = WaiterExclusive | WaiterSpinning;

                    // Obtain the waiters list lock.
                    _lock.Acquire();

                    try
                    {
                        // Try to set the waiters bit.
                        if (Interlocked.CompareExchange(
                                ref _value,
                                value | LockWaiters,
                                value
                                ) != value)
                        {
#if ENABLE_STATISTICS
                            Interlocked.Increment(ref _insWaitBlkRetryCount);
#endif
                            // Unfortunately we have to go back. This is
                            // very wasteful since the waiters list lock
                            // must be released again, but must happen since
                            // the lock may have been released.
                            continue;
                        }

                        // Put our wait block behind other exclusive waiters but
                        // in front of all shared waiters.
                        this.InsertWaitBlock(&waitBlock, ListPosition.LastExclusive);
#if ENABLE_STATISTICS
                        _exclusiveWaitersCount++;

                        if (_peakExclWtrsCount < _exclusiveWaitersCount)
                        {
                            _peakExclWtrsCount = _exclusiveWaitersCount;
                        }
#endif
                    }
                    finally
                    {
                        _lock.Release();
                    }

#if ENABLE_STATISTICS
                    Interlocked.Increment(ref _acqExclBlkCount);
#endif
                    this.Block(&waitBlock);

                    // Go back and try again.
                    continue;
                }

#if ENABLE_STATISTICS
                Interlocked.Increment(ref _acqExclContCount);
#endif
                i++;
            }
        }