internal void Release(Guid dbGuid, AmDbLockReason lockReason) { int currentManagedThreadId = Environment.CurrentManagedThreadId; AmTrace.Debug("releasing lock for db={0} requester={1} reason={2}", new object[] { dbGuid, currentManagedThreadId, lockReason }); lock (this.m_locker) { AmDbLock.LockData lockData = null; if (this.m_lockTable.TryGetValue(dbGuid, out lockData) && lockData.ThreadId == currentManagedThreadId) { lockData.RefCount--; if (lockData.RefCount == 0) { this.m_lockTable.Remove(dbGuid); } } } AmTrace.Debug("lock released for db={0} requester={1}", new object[] { dbGuid, currentManagedThreadId }); }
private static void WarnIfSleepingForEver(Guid dbGuid, int timeSlept, AmDbLockReason lockReason) { if (timeSlept % 10000 == 0) { ReplayEventLogConstants.Tuple_DatabaseOperationLockIsTakingLongTime.LogEvent(null, new object[] { dbGuid, timeSlept, lockReason }); } }
public static AmDatabaseOperationLock Lock(Guid dbId, AmDbLockReason reason, TimeSpan?timeout) { AmDatabaseOperationLock amDatabaseOperationLock = null; AmDatabaseOperationLock amDatabaseOperationLock2 = new AmDatabaseOperationLock(); amDatabaseOperationLock2.m_reason = reason; amDatabaseOperationLock2.m_dbId = dbId; amDatabaseOperationLock2.m_threadId = AmDatabaseOperationLock.GetThreadId(); lock (AmDatabaseOperationLock.s_lockTable) { if (AmDatabaseOperationLock.s_lockTable.TryGetValue(dbId, out amDatabaseOperationLock) && amDatabaseOperationLock != null) { AmTrace.Error("AmDatabaseOperationLock: conflict on db {0}. Requesting for {1} but held by {2} for {3}", new object[] { dbId, reason, amDatabaseOperationLock.ThreadId, amDatabaseOperationLock.Reason }); if (timeout == null || timeout.Value.Ticks == 0L || amDatabaseOperationLock.m_waiter != null) { throw new AmDbLockConflictException(dbId, reason.ToString(), amDatabaseOperationLock.Reason.ToString()); } amDatabaseOperationLock2.m_waiterEvent = new ManualResetEvent(false); amDatabaseOperationLock2.m_mustWaitForLock = true; amDatabaseOperationLock.m_waiter = amDatabaseOperationLock2; } else { AmDatabaseOperationLock.s_lockTable[dbId] = amDatabaseOperationLock2; amDatabaseOperationLock2.m_holdingLock = true; } } if (amDatabaseOperationLock2.m_mustWaitForLock) { amDatabaseOperationLock2.WaitForLock(timeout.Value, amDatabaseOperationLock); } AmTrace.Debug("AmDatabaseOperationLock({0},{1}) : lock obtained", new object[] { dbId, reason }); return(amDatabaseOperationLock2); }
internal bool Lock(Guid dbGuid, AmDbLockReason lockReason) { bool flag = false; int num = 0; int currentManagedThreadId = Environment.CurrentManagedThreadId; AmTrace.Debug("Trying to acquire lock for db={0} requester={1} reason={2}", new object[] { dbGuid, currentManagedThreadId, lockReason }); do { lock (this.m_locker) { AmDbLock.LockData lockData = null; if (this.m_lockTable.TryGetValue(dbGuid, out lockData)) { AmTrace.Debug("lock already held for db={0} heldby={1} current={2} reason={3}", new object[] { dbGuid, lockData.ThreadId, currentManagedThreadId, lockData.Reason }); if (lockData.ThreadId == currentManagedThreadId) { lockData.RefCount++; flag = true; AmTrace.Debug("same thread has requested lock db={0} heldby={1} refcount={2}", new object[] { dbGuid, lockData.ThreadId, lockData.RefCount }); } } else { lockData = new AmDbLock.LockData(currentManagedThreadId, lockReason); this.m_lockTable[dbGuid] = lockData; flag = true; AmTrace.Debug("lock created for db={0} owner={1} reason={2}", new object[] { dbGuid, lockData.ThreadId, lockData.Reason }); } } if (flag) { break; } AmTrace.Debug("sleeping to get the lock again for db={0} requester={1} reason={2} sleptSoFar={3}", new object[] { dbGuid, currentManagedThreadId, lockReason, num }); Thread.Sleep(500); num += 500; AmDbLock.WarnIfSleepingForEver(dbGuid, num, lockReason); }while (!this.IsExiting); if (this.IsExiting && flag) { this.Release(dbGuid, lockReason); flag = false; } AmTrace.Debug("Got lock!! db={0} requester={1}", new object[] { dbGuid, currentManagedThreadId }); return(flag); }
internal LockData(int threadId, AmDbLockReason lockReason) { this.m_reason = lockReason; this.m_threadId = threadId; this.m_refCount = 1; }