コード例 #1
0
        /// <summary>
        /// Acquires a reader lock.
        /// </summary>
        /// <returns>An object (considered opaque by client code) that should be disposed
        /// once the lock is not needed.</returns>
        /// <remarks>It is strongly recommended to use the <b>using</b> construct with
        /// this method.</remarks>
        public Cookie AcquireReadLock()
        {
            if (this.@lock == null)
            {
                return(new Cookie(CookieAction.None, null, null));
            }

            CookieAction action;

            if ([email protected] && [email protected] && [email protected])
            {
                action = CookieAction.ExitReadLock;
                DeadlockMonitor.EnterWaiting(@lock, writeLock, lockedObject);
                if ([email protected](WarningTimeout))
                {
                    Debug.Print("Acquiring a read lock on {0} from thread {1} ({2}) is taking longer than expected.",
                                lockedObject, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.Name);
                    DeadlockMonitor.DetectDeadlocks();
                    @lock.EnterReadLock();
                }
                DeadlockMonitor.ExitWaiting(@lock, writeLock);
                DeadlockMonitor.EnterAcquired(@lock, readLock, lockedObject);
            }
            else
            {
                action = CookieAction.None;
            }

            return(new Cookie(action, this, GetStackTrace()));
        }
コード例 #2
0
            /// <inheritdoc />
            public void Dispose()
            {
                switch (this.action)
                {
                case CookieAction.None:
                    break;

                case CookieAction.ExitReadLock:
                    [email protected]();
                    DeadlockMonitor.ExitAcquired(this.parent.@lock, readLock);
                    break;

                case CookieAction.ExitWriteLock:
                    [email protected]();
                    DeadlockMonitor.ExitAcquired(this.parent.@lock, writeLock);
                    break;

                case CookieAction.ExitWriteAndUpgradeableReadLock:
                    [email protected]();
                    [email protected]();
                    DeadlockMonitor.ExitAcquired(this.parent.@lock, writeLock);
                    DeadlockMonitor.ExitAcquired(this.parent.@lock, upgradableReadLock);
                    break;

                case CookieAction.EnterWriteLock:
                    DeadlockMonitor.EnterWaiting(this.parent.@lock, readLock, this.parent.lockedObject);
                    DeadlockMonitor.EnterWaiting(this.parent.@lock, writeLock, this.parent.lockedObject);
                    DeadlockMonitor.EnterWaiting(this.parent.@lock, upgradableReadLock, this.parent.lockedObject);

                    if ([email protected](WarningTimeout))
                    {
                        Debug.Print("Reacquiring a write lock on {0} from thread {1} ({2}) is taking longer than expected.",
                                    this.parent.lockedObject, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.Name);
                        DeadlockMonitor.DetectDeadlocks();
                        [email protected]();
                    }
                    DeadlockMonitor.ConvertWaitingToAcquired(this.parent.@lock, writeLock, this.parent.lockedObject);
                    DeadlockMonitor.ExitWaiting(this.parent.@lock, readLock);
                    DeadlockMonitor.ExitWaiting(this.parent.@lock, upgradableReadLock);

                    break;

                case CookieAction.ExitUpgrableReaderLock:
                    [email protected]();
                    DeadlockMonitor.ExitAcquired(this.parent.@lock, upgradableReadLock);
                    break;
                }

                this.action = CookieAction.None;

                GC.SuppressFinalize(this);
            }
コード例 #3
0
        /// <summary>
        /// Handler executed before execution of the method to which the current custom attribute is applied.
        /// </summary>
        /// <param name="eventArgs"></param>
        public override void OnEntry(MethodExecutionArgs eventArgs)
        {
            object o = eventArgs.Instance ?? eventArgs.Method.DeclaringType;

            DeadlockMonitor.EnterWaiting(o, null, null);

            if (!Monitor.TryEnter(o, 200))
            {
                DeadlockMonitor.DetectDeadlocks();
                Monitor.Enter(o);
            }
            DeadlockMonitor.ConvertWaitingToAcquired(o, null, null);
        }
コード例 #4
0
        private static void DetectProblems(int i)
        {
            if (i % DeadlockDetectionPeriod / WarningTimeout == 0)
            {
                DeadlockMonitor.DetectDeadlocks();
            }

            // Doing a GC will collect eventual ghost locks.
            if (i % GarbageCollectionDetectionPeriod / WarningTimeout == 0)
            {
                GC.Collect();
            }
        }
コード例 #5
0
        /// <summary>
        /// Acquires an observer lock.
        /// </summary>
        /// <returns>An object (considered opaque by client code) that should be disposed
        /// once the lock is not needed.</returns>
        /// <remarks>It is strongly recommended to use the <b>using</b> construct with
        /// this method.</remarks>
        public Cookie AcquireObserverLock()
        {
            if (this.@lock == null)
            {
                return(new Cookie(CookieAction.None, null, null));
            }

            if ([email protected])
            {
                [email protected]();
                DeadlockMonitor.ExitAcquired(this.@lock, writeLock);
                return(new Cookie(CookieAction.EnterWriteLock, this, GetStackTrace()));
            }
            else
            {
                return(new Cookie(CookieAction.None, this, GetStackTrace()));
            }
        }
コード例 #6
0
        /// <summary>
        /// Acquires an upgradable reader lock.
        /// </summary>
        /// <returns>An object (considered opaque by client code) that should be disposed
        /// once the lock is not needed.</returns>
        /// <remarks>It is strongly recommended to use the <b>using</b> construct with
        /// this method.</remarks>
        public Cookie AcquireUpgradableReadLock()
        {
            if (this.@lock == null)
            {
                return(new Cookie(CookieAction.None, null, null));
            }

            CookieAction action;

            if ([email protected] && [email protected])
            {
                if (@lock.IsReadLockHeld)
                {
                    throw new InvalidOperationException(
                              string.Format("Cannot acquire a write lock on {{{0}}}, because the current thread " +
                                            "already holds a read lock on that object, and acquiring a write lock may cause a deadlock.",
                                            @lock));
                }

                action = CookieAction.ExitUpgrableReaderLock;

                DeadlockMonitor.EnterWaiting(@lock, upgradableReadLock, lockedObject);
                DeadlockMonitor.EnterWaiting(@lock, writeLock, lockedObject);

                if ([email protected](WarningTimeout))
                {
                    Debug.Print("Acquiring a read lock on {0} from thread {1} ({2}) is taking longer than expected.",
                                lockedObject, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.Name);

                    DeadlockMonitor.DetectDeadlocks();
                    @lock.EnterUpgradeableReadLock();
                }
                DeadlockMonitor.ConvertWaitingToAcquired(@lock, upgradableReadLock, lockedObject);
                DeadlockMonitor.ExitWaiting(@lock, writeLock);
            }
            else
            {
                action = CookieAction.None;
            }

            return(new Cookie(action, this, GetStackTrace()));
        }