/// <summary> /// Releases the write lock held by the provided tx. If it is null then an /// attempt to acquire the current transaction from the transaction manager /// will be made. This is to make safe calling this method as an /// <code>afterCompletion()</code> hook where the transaction context is not /// necessarily available. If write count is zero and there are waiting /// transactions in the queue they will be interrupted if they can acquire /// the lock. /// </summary> //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: synchronized void releaseWriteLock(Object tx) throws LockNotFoundException internal virtual void ReleaseWriteLock(object tx) { lock (this) { TxLockElement tle = GetLockElement(tx); if (tle.WriteCount == 0) { throw new LockNotFoundException("" + tx + " don't have writeLock"); } _totalWriteCount = MathUtil.decrementExactNotPastZero(_totalWriteCount); tle.WriteCount = MathUtil.decrementExactNotPastZero(tle.WriteCount); if (tle.Free) { _ragManager.lockReleased(this, tx); if (tle.HasNoRequests()) { _txLockElementMap.Remove(tx); } } // the threads in the waitingList cannot be currentThread // so we only have to wake other elements if writeCount is down to zero // (that is: If writeCount > 0 a waiting thread in the queue cannot be // the thread that holds the write locks because then it would never // have been put into wait mode) if (_totalWriteCount == 0 && _waitingThreadList.Count > 0) { // wake elements in queue until a write lock is found or queue is // empty do { LockRequest lockRequest = _waitingThreadList.RemoveLast(); lockRequest.WaitingThread.Interrupt(); if (lockRequest.LockType == LockType.WRITE) { break; } } while (_waitingThreadList.Count > 0); } } }
/// <summary> /// Releases the read lock held by the provided transaction. If it is null then /// an attempt to acquire the current transaction will be made. This is to /// make safe calling the method from the context of an /// <code>afterCompletion()</code> hook where the tx is locally stored and /// not necessarily available through the tm. If there are waiting /// transactions in the queue they will be interrupted if they can acquire /// the lock. /// </summary> //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: synchronized void releaseReadLock(Object tx) throws LockNotFoundException internal virtual void ReleaseReadLock(object tx) { lock (this) { TxLockElement tle = GetLockElement(tx); if (tle.ReadCount == 0) { throw new LockNotFoundException("" + tx + " don't have readLock"); } _totalReadCount = MathUtil.decrementExactNotPastZero(_totalReadCount); tle.ReadCount = MathUtil.decrementExactNotPastZero(tle.ReadCount); if (tle.Free) { _ragManager.lockReleased(this, tx); if (tle.HasNoRequests()) { _txLockElementMap.Remove(tx); } } if (_waitingThreadList.Count > 0) { LockRequest lockRequest = _waitingThreadList.Last.Value; if (lockRequest.LockType == LockType.WRITE) { // this one is tricky... // if readCount > 0 lockRequest either have to find a waiting read lock // in the queue or a waiting write lock that has all read // locks, if none of these are found it means that there // is a (are) thread(s) that will release read lock(s) in the // near future... if (_totalReadCount == lockRequest.Element.readCount) { // found a write lock with all read locks _waitingThreadList.RemoveLast(); lockRequest.WaitingThread.Interrupt(); } else { IEnumerator <LockRequest> listItr = _waitingThreadList.listIterator(_waitingThreadList.LastIndexOf(lockRequest)); // hm am I doing the first all over again? // think I am if cursor is at lastIndex + 0.5 oh well... while (listItr.hasPrevious()) { lockRequest = listItr.previous(); if (lockRequest.LockType == LockType.WRITE && _totalReadCount == lockRequest.Element.readCount) { // found a write lock with all read locks //JAVA TO C# CONVERTER TODO TASK: .NET enumerators are read-only: listItr.remove(); lockRequest.WaitingThread.Interrupt(); break; } else if (lockRequest.LockType == LockType.READ) { // found a read lock, let it do the job... //JAVA TO C# CONVERTER TODO TASK: .NET enumerators are read-only: listItr.remove(); lockRequest.WaitingThread.Interrupt(); } } } } else { // some thread may have the write lock and released a read lock // if writeCount is down to zero lockRequest can interrupt the waiting // read lock if (_totalWriteCount == 0) { _waitingThreadList.RemoveLast(); lockRequest.WaitingThread.Interrupt(); } } } } }