public override void ReleaseExclusive(ResourceType resourceType, params long[] resourceIds) { _stateHolder.incrementActiveClients(this); try { ConcurrentMap <long, ForsetiLockManager.Lock> resourceTypeLocks = _lockMaps[resourceType.TypeId()]; MutableLongIntMap exclusiveLocks = _exclusiveLockCounts[resourceType.TypeId()]; MutableLongIntMap sharedLocks = _sharedLockCounts[resourceType.TypeId()]; foreach (long resourceId in resourceIds) { if (ReleaseLocalLock(resourceType, resourceId, exclusiveLocks)) { continue; } if (sharedLocks.containsKey(resourceId)) { // We are still holding a shared lock, so we will release it to be reused ForsetiLockManager.Lock @lock = resourceTypeLocks.get(resourceId); if (@lock is SharedLock) { SharedLock sharedLock = ( SharedLock )@lock; if (sharedLock.UpdateLock) { sharedLock.ReleaseUpdateLock(); } else { throw new System.InvalidOperationException("Incorrect state of exclusive lock. Lock should be updated " + "to exclusive before attempt to release it. Lock: " + this); } } else { // in case if current lock is exclusive we swap it to new shared lock SharedLock sharedLock = new SharedLock(this); resourceTypeLocks.put(resourceId, sharedLock); } } else { // we do not hold shared lock so we just releasing it ReleaseGlobalLock(resourceTypeLocks, resourceId); } } } finally { _stateHolder.decrementActiveClients(); } }
public override bool TryExclusiveLock(ResourceType resourceType, long resourceId) { _hasLocks = true; _stateHolder.incrementActiveClients(this); try { ConcurrentMap <long, ForsetiLockManager.Lock> lockMap = _lockMaps[resourceType.TypeId()]; MutableLongIntMap heldLocks = _exclusiveLockCounts[resourceType.TypeId()]; int heldCount = heldLocks.getIfAbsent(resourceId, -1); if (heldCount != -1) { // We already have a lock on this, just increment our local reference counter. heldLocks.put(resourceId, Math.incrementExact(heldCount)); return(true); } // Grab the global lock ForsetiLockManager.Lock @lock; if ((@lock = lockMap.putIfAbsent(resourceId, _myExclusiveLock)) != null) { if (@lock is SharedLock && _sharedLockCounts[resourceType.TypeId()].containsKey(resourceId)) { SharedLock sharedLock = ( SharedLock )@lock; if (sharedLock.TryAcquireUpdateLock(this)) { if (sharedLock.NumberOfHolders() == 1) { heldLocks.put(resourceId, 1); return(true); } else { sharedLock.ReleaseUpdateLock(); return(false); } } } return(false); } heldLocks.put(resourceId, 1); return(true); } finally { _stateHolder.decrementActiveClients(); } }
/// <summary> /// Attempt to upgrade a share lock that we hold to an exclusive lock. </summary> //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: private boolean tryUpgradeToExclusiveWithShareLockHeld(org.neo4j.storageengine.api.lock.LockTracer tracer, org.neo4j.storageengine.api.lock.LockWaitEvent priorEvent, org.neo4j.storageengine.api.lock.ResourceType resourceType, long resourceId, SharedLock sharedLock, int tries, long waitStartMillis) throws org.neo4j.storageengine.api.lock.AcquireLockTimeoutException private bool TryUpgradeToExclusiveWithShareLockHeld(LockTracer tracer, LockWaitEvent priorEvent, ResourceType resourceType, long resourceId, SharedLock sharedLock, int tries, long waitStartMillis) { if (sharedLock.TryAcquireUpdateLock(this)) { LockWaitEvent waitEvent = null; try { // Now we just wait for all clients to release the the share lock while (sharedLock.NumberOfHolders() > 1) { AssertValid(waitStartMillis, resourceType, resourceId); if (waitEvent == null && priorEvent == null) { waitEvent = tracer.WaitForLock(true, resourceType, resourceId); } WaitFor(sharedLock, resourceType, resourceId, true, tries++); } return(true); } catch (Exception e) { sharedLock.ReleaseUpdateLock(); if (e is DeadlockDetectedException || e is LockClientStoppedException) { throw ( Exception )e; } throw new TransactionFailureException("Failed to upgrade shared lock to exclusive: " + sharedLock, e); } finally { if (waitEvent != null) { waitEvent.Close(); } ClearWaitList(); _waitingForLock = null; } } return(false); }