Beispiel #1
0
        /// <summary />
        public AcquireReaderLock(Guid id, string traceInfo)
        {
            this.LockTime = 0;
            m_Lock        = LockingManager.GetLocker(id);
            _id           = id;
            if (!ConfigHelper.AllowReadLocking)
            {
                return;
            }

            this.ReadLockCount       = m_Lock.CurrentReadCount;
            this.WaitingLocksOnEntry = m_Lock.WaitingWriteCount;
            if (this.WaitingLocksOnEntry > 10)
            {
                LoggerCQ.LogWarning($"AcquireReaderLock Waiting Writer Locks: Count={this.WaitingLocksOnEntry}, RepositoryId={id}, TraceInfo={traceInfo}");
            }

            if (!m_Lock.TryEnterReadLock(TimeOut))
            {
                _inError = true;

                throw new Exception("Could not get reader lock: " +
                                    ((m_Lock.ObjectId == Guid.Empty) ? string.Empty : $"ID={m_Lock.ObjectId}") +
                                    $", CurrentReadCount={m_Lock.CurrentReadCount}" +
                                    $", WaitingReadCount={m_Lock.WaitingReadCount}" +
                                    $", WaitingWriteCount={m_Lock.WaitingWriteCount}" +
                                    $", HoldingThread={m_Lock.HoldingThreadId}" +
                                    $", TraceInfo={m_Lock.TraceInfo}" +
                                    $", LockFailTime={(int)DateTime.Now.Subtract(_initTime).TotalMilliseconds}" +
                                    $", WriteHeldTime={m_Lock.WriteHeldTime}");
            }

            this.LockTime = (int)DateTime.Now.Subtract(_initTime).TotalMilliseconds;
            Interlocked.Increment(ref _counter);
            _lockIndex = _counter;
            m_Lock.HeldReads.AddOrUpdate(_lockIndex, DateTime.Now, (key, value) => DateTime.Now);
            m_Lock.TraceInfo       = traceInfo;
            m_Lock.HoldingThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
        }
Beispiel #2
0
        public AcquireWriterLock(Guid id, string traceInfo)
        {
            if (id == Guid.Empty)
            {
                return;
            }

            m_Lock = LockingManager.GetLocker(id);
            if (!ConfigHelper.AllowWriteLocking)
            {
                return;
            }

            this.ReadLockCount       = m_Lock.CurrentReadCount;
            this.WaitingLocksOnEntry = m_Lock.WaitingWriteCount;
            if (this.WaitingLocksOnEntry > 10)
            {
                LoggerCQ.LogWarning($"AcquireWriterLock Waiting Writer Locks: Count={this.WaitingLocksOnEntry}, RepositoryId={id}, TraceInfo={traceInfo}");
            }

            //If there is another write lock held then wait to enter and give the read locks to run
            //This is a hack to address the issue with the lock object: it prioritizes writes and starves reads
            var lockHeld = false;

            if (traceInfo == RepositoryManager.TraceInfoUpdateData)
            {
                while (m_Lock.IsWriteLockHeld && DateTime.Now.Subtract(_initTime).TotalMilliseconds < 10000)
                {
                    System.Threading.Thread.Sleep(20);
                    lockHeld = true;
                }
            }

            var delay = (int)DateTime.Now.Subtract(_initTime).TotalMilliseconds;

            if (lockHeld)
            {
                LoggerCQ.LogDebug($"AcquireWriterLock: Held={delay}, RepositoryId={id}, TraceInfo={traceInfo}");
            }

            var timeoutValue = TimeOut - delay;

            if (!m_Lock.TryEnterWriteLock(timeoutValue))
            {
                _inError = true;
                RepositoryManager.SystemCore.LogLockStat(new LockInfoItem
                {
                    CurrentReadCount  = m_Lock.CurrentReadCount,
                    Elapsed           = (int)DateTime.Now.Subtract(_initTime).TotalMilliseconds,
                    Failure           = true,
                    IsWriteLockHeld   = m_Lock.IsWriteLockHeld,
                    ThreadId          = (m_Lock.HoldingThreadId == null) ? 0 : m_Lock.HoldingThreadId.Value,
                    WaitingReadCount  = m_Lock.WaitingReadCount,
                    WaitingWriteCount = m_Lock.WaitingWriteCount,
                    TraceInfo         = traceInfo,
                });

                var lapses = string.Join("-", m_Lock.HeldReads.Values.ToList().Select(x => (int)DateTime.Now.Subtract(x).TotalSeconds).ToList());
                throw new Exception("Could not get writer lock: " +
                                    ((m_Lock.ObjectId == Guid.Empty) ? string.Empty : $"ID={m_Lock.ObjectId}") +
                                    $", CurrentReadCount={m_Lock.CurrentReadCount}" +
                                    $", WaitingReadCount={m_Lock.WaitingReadCount}" +
                                    $", WaitingWriteCount={m_Lock.WaitingWriteCount}" +
                                    $", HoldingThread={m_Lock.HoldingThreadId}" +
                                    $", TraceInfo={m_Lock.TraceInfo}" +
                                    $", WriteHeldTime={m_Lock.WriteHeldTime}" +
                                    $", LockFailTime={(int)DateTime.Now.Subtract(_initTime).TotalMilliseconds}" +
                                    $", Lapses={lapses}");
            }

            this.LockTime            = (int)DateTime.Now.Subtract(_initTime).TotalMilliseconds;
            m_Lock.TraceInfo         = traceInfo;
            m_Lock.WriteLockHeldTime = DateTime.Now;
            m_Lock.HoldingThreadId   = System.Threading.Thread.CurrentThread.ManagedThreadId;
        }