Ejemplo n.º 1
0
 private void RegisterLockAcquired(object tx, TxLockElement tle)
 {
     if (tle.Free)
     {
         _ragManager.lockAcquired(this, tx);
     }
 }
Ejemplo n.º 2
0
        // in case of spurious wake up, deadlock during spurious wake up, termination
        // when we already have request in a queue we need to clean it up
        private void CleanupWaitingListRequests(LockRequest lockRequest, TxLockElement lockElement, bool addLockRequest)
        {
            if (lockRequest != null && (lockElement.Terminated || !addLockRequest))
            {
//JAVA TO C# CONVERTER TODO TASK: There is no .NET LinkedList equivalent to the Java 'remove' method:
                _waitingThreadList.remove(lockRequest);
            }
        }
Ejemplo n.º 3
0
        private TxLockElement GetLockElement(object tx)
        {
            TxLockElement tle = _txLockElementMap[tx];

            if (tle == null)
            {
                throw new LockNotFoundException("No transaction lock element found for " + tx);
            }
            return(tle);
        }
Ejemplo n.º 4
0
        private TxLockElement GetOrCreateLockElement(object tx)
        {
            AssertTransaction(tx);
            TxLockElement tle = _txLockElementMap[tx];

            if (tle == null)
            {
                _txLockElementMap[tx] = tle = new TxLockElement(tx);
            }
            return(tle);
        }
Ejemplo n.º 5
0
 // for specified transaction object mark all lock elements as terminated
 // and interrupt all waiters
 internal virtual void TerminateLockRequestsForLockTransaction(object lockTransaction)
 {
     lock (this)
     {
         TxLockElement lockElement = _txLockElementMap[lockTransaction];
         if (lockElement != null && !lockElement.Terminated)
         {
             lockElement.Terminated = true;
             foreach (LockRequest lockRequest in _waitingThreadList)
             {
                 if (lockRequest.Element.tx.Equals(lockTransaction))
                 {
                     lockRequest.WaitingThread.Interrupt();
                 }
             }
         }
     }
 }
Ejemplo n.º 6
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.º 7
0
        internal virtual bool TryAcquireWriteLock(object tx)
        {
            lock (this)
            {
                TxLockElement tle = GetOrCreateLockElement(tx);

                try
                {
                    if (tle.Terminated || (_totalWriteCount > tle.WriteCount) || (_totalReadCount > tle.ReadCount))
                    {
                        return(false);
                    }

                    RegisterWriteLockAcquired(tx, tle);
                    return(true);
                }
                finally
                {
                    // if deadlocked, remove marking so lock is removed when empty
                    Unmark();
                }
            }
        }
Ejemplo n.º 8
0
 private void RegisterWriteLockAcquired(object tx, TxLockElement tle)
 {
     RegisterLockAcquired(tx, tle);
     _totalWriteCount = Math.incrementExact(_totalWriteCount);
     tle.WriteCount   = Math.incrementExact(tle.WriteCount);
 }
Ejemplo n.º 9
0
 private void RegisterReadLockAcquired(object tx, TxLockElement tle)
 {
     RegisterLockAcquired(tx, tle);
     _totalReadCount = Math.incrementExact(_totalReadCount);
     tle.ReadCount   = Math.incrementExact(tle.ReadCount);
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Tries to acquire write lock for a given transaction. If
        /// <CODE>this.writeCount</CODE> is greater than the currents tx's write
        /// count or the read count is greater than the currents tx's read count the
        /// transaction has to wait and the <seealso cref="RagManager.checkWaitOn"/> method is
        /// invoked for deadlock detection.
        /// <p/>
        /// If the lock can be acquires the lock count is updated on <CODE>this</CODE>
        /// and the transaction lock element (tle).
        /// Waiting for a lock can also be terminated. In that case waiting thread will be interrupted and corresponding
        /// <seealso cref="org.neo4j.kernel.impl.locking.community.RWLock.TxLockElement"/> will be marked as terminated.
        /// In that case lock will not be acquired and false will be return as result of acquisition
        /// </summary>
        /// <returns> true is lock was acquired, false otherwise </returns>
        /// <exception cref="DeadlockDetectedException"> if a deadlock is detected </exception>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: synchronized boolean acquireWriteLock(org.neo4j.storageengine.api.lock.LockTracer tracer, Object tx) throws org.neo4j.kernel.DeadlockDetectedException
        internal virtual bool AcquireWriteLock(LockTracer tracer, object tx)
        {
            lock (this)
            {
                TxLockElement tle = GetOrCreateLockElement(tx);

                LockRequest   lockRequest = null;
                LockWaitEvent waitEvent   = null;
                // used to track do we need to add lock request to a waiting queue or we still have it there
                bool addLockRequest = true;
                try
                {
                    tle.IncrementRequests();
                    Thread currentThread = currentThread();

                    long lockAcquisitionTimeBoundary = _clock.millis() + _lockAcquisitionTimeoutMillis;
                    while (!tle.Terminated && (_totalWriteCount > tle.WriteCount || _totalReadCount > tle.ReadCount))
                    {
                        AssertNotExpired(lockAcquisitionTimeBoundary);
                        _ragManager.checkWaitOn(this, tx);

                        if (addLockRequest)
                        {
                            lockRequest = new LockRequest(tle, WRITE, currentThread);
                            _waitingThreadList.AddFirst(lockRequest);
                        }

                        if (waitEvent == null)
                        {
                            waitEvent = tracer.WaitForLock(true, _resource.type(), _resource.resourceId());
                        }
                        addLockRequest = WaitUninterruptedly(lockAcquisitionTimeBoundary);
                        _ragManager.stopWaitOn(this, tx);
                    }

                    if (!tle.Terminated)
                    {
                        RegisterWriteLockAcquired(tx, tle);
                        return(true);
                    }
                    else
                    {
                        // in case if lock element was interrupted and it was never register before
                        // we need to clean it from lock element map
                        // if it was register before it will be cleaned up during standard lock release call
                        if (tle.Requests == 1 && tle.Free)
                        {
                            _txLockElementMap.Remove(tx);
                        }
                        return(false);
                    }
                }
                finally
                {
                    if (waitEvent != null)
                    {
                        waitEvent.Close();
                    }
                    CleanupWaitingListRequests(lockRequest, tle, addLockRequest);
                    // for cases when spurious wake up was the reason why we waked up, but also there
                    // was an interruption as described at 17.2 just clearing interruption flag
                    interrupted();
                    // if deadlocked, remove marking so lock is removed when empty
                    tle.DecrementRequests();
                    Unmark();
                }
            }
        }
Ejemplo n.º 11
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();
                        }
                    }
                }
            }
        }
Ejemplo n.º 12
0
 internal LockRequest(TxLockElement element, LockType lockType, Thread thread)
 {
     this.Element       = element;
     this.LockType      = lockType;
     this.WaitingThread = thread;
 }