⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lockcontrol.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*   Derby - Class org.apache.derby.impl.services.locks.LockControl   Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable.   Licensed under the Apache License, Version 2.0 (the "License");   you may not use this file except in compliance with the License.   You may obtain a copy of the License at      http://www.apache.org/licenses/LICENSE-2.0   Unless required by applicable law or agreed to in writing, software   distributed under the License is distributed on an "AS IS" BASIS,   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   See the License for the specific language governing permissions and   limitations under the License. */package org.apache.derby.impl.services.locks;import org.apache.derby.iapi.services.locks.Lockable;import org.apache.derby.iapi.services.locks.Latch;import org.apache.derby.iapi.services.sanity.SanityManager;import java.util.Dictionary;import java.util.Stack;import java.util.List;import java.util.ListIterator;/**	A LockControl contains a reference to the item being locked	and doubly linked lists for the granted locks and the waiting	locks.	<P>	MT - Mutable - Container object : single thread required*/public class LockControl implements Control {	private final Lockable		ref;	/**		This lock control uses an optimistic locking scheme.		When the first lock on an object is granted it		simply sets firstGrant to be that object, removing the		need to allocate a list if no other locks are granted		before the first lock is release. If a second lock		is granted then a list is allocated and the		firstGrant lock is moved into the list. Once a list		has been created it is always used.	*/	private Lock				firstGrant;	private List				granted;	private List				waiting;	private Lock				lastPossibleSkip;	protected LockControl(Lock firstLock, Lockable ref) {		super();		this.ref = ref;		// System.out.println("new lockcontrol");		firstGrant = firstLock;	}	// make a copy by cloning the granted and waiting lists	private LockControl(LockControl copyFrom)	{		super();		this.ref = copyFrom.ref;		this.firstGrant = copyFrom.firstGrant;		if (copyFrom.granted != null)			this.granted = new java.util.LinkedList(copyFrom.granted);		if (copyFrom.waiting != null)			this.waiting = new java.util.LinkedList(copyFrom.waiting);		this.lastPossibleSkip = copyFrom.lastPossibleSkip;	}		public LockControl getLockControl() {		return this;	}	/**	*/	public boolean isEmpty() {		// if we are locked then we are not empty		if (!isUnlocked())			return false;		return (waiting == null) || waiting.isEmpty();	}	/**		Grant this lock.	*/	void grant(Lock lockItem) {		lockItem.grant();		List lgranted = granted;				if (lgranted == null) {			if (firstGrant == null) {				// first ever lock on this item				firstGrant = lockItem;			} else {				// second ever lock on this item				lgranted = granted = new java.util.LinkedList();				lgranted.add(firstGrant);				lgranted.add(lockItem);				firstGrant = null;			}		} else {			// this grants the lock			lgranted.add(lockItem);		}	}	/**	*/	public boolean unlock(Latch lockInGroup, int unlockCount) {		// note that lockInGroup is not the actual Lock object held in the lock set.		if (unlockCount == 0)			unlockCount = lockInGroup.getCount();		List lgranted = granted;					// start at the begining of the list when there is one		for (int index = 0; unlockCount > 0; ) {			Lock lockInSet;			if (firstGrant != null) {				if (SanityManager.DEBUG) {					SanityManager.ASSERT(lockInGroup.equals(firstGrant));				}				lockInSet = firstGrant;			} else {				// index = lgranted.indexOf(index, lgranted.size() - 1, lockInGroup);				/*List*/ index = lgranted.indexOf(lockInGroup);							if (SanityManager.DEBUG) {					SanityManager.ASSERT(index != -1);				}				lockInSet = (Lock) lgranted.get(index);			}			unlockCount -= lockInSet.unlock(unlockCount);			if (lockInSet.getCount() != 0) {				if (SanityManager.DEBUG) {					if (unlockCount != 0)						SanityManager.THROWASSERT("locked item didn't reduce unlock count to zero " + unlockCount);				}				continue;			}			if (firstGrant == lockInSet) {				if (SanityManager.DEBUG) {					if (unlockCount != 0)						SanityManager.THROWASSERT("item is still locked! " + unlockCount);				}				firstGrant = null;			}			else {				lgranted.remove(index);			}		}		return true;	}	/**        This routine can be called to see if a lock currently on the wait        list could be granted. If this lock has waiters ahead of it		then we do not jump over the waiter(s) even if we can be granted.		 This avoids the first waiter being starved out.	*/    public boolean isGrantable(    boolean noWaitersBeforeMe,    Object  compatabilitySpace,     Object  qualifier)    {		if (isUnlocked())			return true;        boolean grantLock    = false;		Lockable lref = ref;		List lgranted = granted;        {            // Check to see if the only locks on the granted queue that            // we are incompatible with are locks we own.            boolean selfCompatible = lref.lockerAlwaysCompatible();			int index = 0;			int endIndex = firstGrant == null ? lgranted.size() : 0;			do {				Lock gl = firstGrant == null ? (Lock) lgranted.get(index) : firstGrant;                boolean sameSpace =                     (gl.getCompatabilitySpace().equals(compatabilitySpace));                if (sameSpace && selfCompatible)                 {                    // if it's one of our locks and we are always compatible                     // with our own locks then yes, we can be granted.                                        grantLock = true;                    continue;                }                else if (!lref.requestCompatible(qualifier, gl.getQualifier()))                 {                    // If we are not compatible with some already granted lock                    // then we can't be granted, give up right away.                                        grantLock = false;                    break;                }                else                {                    // We are compatible with this lock, if it's our own or                     // there are no other waiters then we can be granted.                                    if (sameSpace || noWaitersBeforeMe)                     {                        grantLock = true;                    }                }            } while (++index < endIndex);		}        return(grantLock);    }	/**		Add a lock into this control, granted it if possible.		This can be entered in several states.		</OL>		<LI>The Lockable is locked (granted queue not empty), and there are no waiters (waiting queue is empty)		<LI>The Lockable is locked and there are waiters		<LI>The Lockable is locked and there are waiters and the first is potentially granted		<LI>The Lockable is unlocked and there are waiters and the first is potentially granted. Logically the item is		    still locked, it's just that the lock has just been released and the first waker has not woken up yet.		</OL>		This call is never entered when the object is unlocked and there are no waiters.			1) The Lockable has just been unlocked, 	*/	public Lock addLock(LockSet ls, Object compatabilitySpace, Object qualifier) {		if (SanityManager.DEBUG) {			if (!(!isUnlocked() || (firstWaiter() != null)))				SanityManager.THROWASSERT("entered in totally unlocked mode " + isUnlocked() + " " + (firstWaiter() != null));		}		// If there are other waiters for this lock then we		// will only grant this lock if we already hold a lock.		// This stops a lock being frozen out while compatible locks		// jump past it.		boolean grantLock = false;				boolean otherWaiters = (firstWaiter() != null);		Lock lockItem = null;		Lockable lref = ref;		// If we haven't been able to grant the lock yet then see if we hold a         // lock already that we are compatible with and there are no granted         // incompatible locks. If the object appears unlocked (due to a just         // released lock, but the first waiter hasn't woken yet)		// then we obviously don't hold a lock, so just join the wait queue.		boolean spaceHasALock = false;		boolean noGrantAtAll = false;		if (!grantLock && !isUnlocked()) {			boolean selfCompatible = lref.lockerAlwaysCompatible();						int index = 0;			int endIndex = firstGrant == null ? granted.size() : 0;			do {				Lock gl = firstGrant == null ? (Lock) granted.get(index) : firstGrant;				boolean sameSpace = (gl.getCompatabilitySpace().equals(compatabilitySpace));				// if it's one of our locks and we are always compatible with                 // our own locks then yes, we can be granted.				if (sameSpace && selfCompatible) {					spaceHasALock = true;					if (noGrantAtAll)						break;					if (qualifier == gl.getQualifier())						lockItem = gl;					grantLock = true;					continue;				}								// If we are not compatible with some already granted lock                // then we can't be granted, give up right away.				if (!lref.requestCompatible(qualifier, gl.getQualifier())) {					grantLock = false;					lockItem = null;					// we can't give up rightaway if spaceHasALock is false					// because we need to ensure that canSkip is set correctly					if (spaceHasALock)						break;					noGrantAtAll = true;				}				// We are compatible with this lock, if it's our own or there                // are no other waiters then yes we can still be granted ...								if (!noGrantAtAll && (sameSpace || !otherWaiters)) {					grantLock = true;				}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -