Ejemplo n.º 1
0
        /// <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);
                }
            }
        }
Ejemplo n.º 2
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();
                        }
                    }
                }
            }
        }