Return-Path: Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: (qmail 36940 invoked from network); 6 Mar 2007 09:18:04 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 6 Mar 2007 09:18:04 -0000 Received: (qmail 20464 invoked by uid 500); 6 Mar 2007 09:18:13 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 20442 invoked by uid 500); 6 Mar 2007 09:18:13 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 20430 invoked by uid 99); 6 Mar 2007 09:18:12 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 06 Mar 2007 01:18:12 -0800 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 06 Mar 2007 01:18:03 -0800 Received: by eris.apache.org (Postfix, from userid 65534) id E3CC81A9838; Tue, 6 Mar 2007 01:17:42 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r515040 - in /db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks: Control.java Deadlock.java Lock.java LockControl.java LockSet.java LockSpace.java LockTable.java SinglePool.java Date: Tue, 06 Mar 2007 09:17:42 -0000 To: derby-commits@db.apache.org From: kahatlen@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070306091742.E3CC81A9838@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: kahatlen Date: Tue Mar 6 01:17:41 2007 New Revision: 515040 URL: http://svn.apache.org/viewvc?view=rev&rev=515040 Log: DERBY-2327 (partial) Reduce monitor contention in LockSet Encapsulated more of the lock table functionality in LockSet: - created a new interface (LockTable) which LockSet implements - replaced all references to LockSet with references to the new LockTable interface - moved code that explicitly synchronized on the LockSet object from LockSpace.unlockReference() and SinglePool.zeroDurationlockObject() to LockSet so that the granularity of the synchronization can be controlled by the LockSet implementation alone - added setter methods for deadlock timeout and wait timeout Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockTable.java (with props) Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/Control.java db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/Deadlock.java db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/Lock.java db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockControl.java db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockSet.java db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockSpace.java db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/SinglePool.java Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/Control.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/Control.java?view=diff&rev=515040&r1=515039&r2=515040 ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/Control.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/Control.java Tue Mar 6 01:17:41 2007 @@ -25,6 +25,7 @@ import org.apache.derby.iapi.services.locks.Lockable; import org.apache.derby.iapi.services.locks.Latch; import java.util.List; +import java.util.Map; public interface Control { @@ -49,7 +50,7 @@ public boolean unlock(Latch lockInGroup, int unlockCount); - public void addWaiters(java.util.Dictionary waiters); + public void addWaiters(Map waiters); public Lock getFirstGrant(); Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/Deadlock.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/Deadlock.java?view=diff&rev=515040&r1=515039&r2=515040 ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/Deadlock.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/Deadlock.java Tue Mar 6 01:17:41 2007 @@ -50,7 +50,9 @@ *
* MT - must be synchronized on the LockSet object. */ - static Object[] look(SinglePool factory, LockSet set, LockControl control, ActiveLock startingLock, byte deadlockWake) { + static Object[] look(SinglePool factory, LockTable set, + LockControl control, ActiveLock startingLock, + byte deadlockWake) { // step one, get a list of all waiters Dictionary waiters = Deadlock.getWaiters(set); @@ -180,7 +182,7 @@ grants.remove(grants.size() - 1); } - private static Hashtable getWaiters(LockSet set) { + private static Hashtable getWaiters(LockTable set) { Hashtable waiters = new Hashtable(); set.addWaiters(waiters); return waiters; Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/Lock.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/Lock.java?view=diff&rev=515040&r1=515039&r2=515040 ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/Lock.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/Lock.java Tue Mar 6 01:17:41 2007 @@ -28,6 +28,7 @@ import org.apache.derby.iapi.services.sanity.SanityManager; import java.util.List; +import java.util.Map; /** A Lock represents a granted or waiting lock request. @@ -208,7 +209,7 @@ return false; } - public void addWaiters(java.util.Dictionary waiters) { + public void addWaiters(Map waiters) { } public Lock getFirstGrant() { return this; Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockControl.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockControl.java?view=diff&rev=515040&r1=515039&r2=515040 ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockControl.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockControl.java Tue Mar 6 01:17:41 2007 @@ -27,10 +27,10 @@ import org.apache.derby.iapi.services.sanity.SanityManager; -import java.util.Dictionary; import java.util.Stack; import java.util.List; import java.util.ListIterator; +import java.util.Map; /** A LockControl contains a reference to the item being locked @@ -268,7 +268,7 @@ 1) The Lockable has just been unlocked, */ - public Lock addLock(LockSet ls, CompatibilitySpace compatibilitySpace, + public Lock addLock(LockTable ls, CompatibilitySpace compatibilitySpace, Object qualifier) { if (SanityManager.DEBUG) { @@ -412,7 +412,7 @@ /** Get the next waiting lock (if any). */ - ActiveLock getNextWaiter(ActiveLock item, boolean remove, LockSet ls) { + ActiveLock getNextWaiter(ActiveLock item, boolean remove, LockTable ls) { ActiveLock nextWaitingLock = null; @@ -505,7 +505,7 @@ Give up waiting up on a lock */ - protected void giveUpWait(Object item, LockSet ls) { + protected void giveUpWait(Object item, LockTable ls) { int count = removeWaiter(waiting, item, ls); if (item == lastPossibleSkip) @@ -526,7 +526,7 @@ */ /** - Add the waiters of this lock into this Dictionary object. + Add the waiters of this lock into this Map object.
Each waiting thread gets two entries in the hashtable
    @@ -534,7 +534,7 @@
  1. key=ActiveLock - value={LockControl for first waiter|ActiveLock of previosue waiter}
*/ - public void addWaiters(Dictionary waiters) { + public void addWaiters(Map waiters) { if ((waiting == null) || waiting.isEmpty()) return; @@ -616,11 +616,11 @@ * * @param waiting The list of waiters to add to * @param lockItem The lock request - * @param ls The LockSet + * @param ls The lock table */ private void addWaiter(List waiting, Lock lockItem, - LockSet ls) { + LockTable ls) { // Add lock to the waiting list waiting.add(lockItem); @@ -633,11 +633,11 @@ * Remove and return the first lock request from a list of waiters. * * @param waiting The list of waiters to pop from - * @param ls The LockSet + * @param ls The lock table * * @return The removed lock request */ - private Object popFrontWaiter(List waiting, LockSet ls) { + private Object popFrontWaiter(List waiting, LockTable ls) { // Maintain count of waiters ls.oneLessWaiter(); @@ -652,13 +652,13 @@ * * @param waiting The list of waiters to pop from * @param index The index at which to remove the lock request - * @param ls The LockSet + * @param ls The lock table * * @return The removed lock request */ private Object removeWaiter(List waiting, int index, - LockSet ls) { + LockTable ls) { // Maintain count of waiters ls.oneLessWaiter(); @@ -671,13 +671,13 @@ * * @param waiting The list of waiters to pop from * @param item The item to remove - * @param ls The LockSet + * @param ls The lock table * * @return The number of items removed */ private int removeWaiter(List waiting, Object item, - LockSet ls) { + LockTable ls) { // Maintain count of waiters ls.oneLessWaiter(); Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockSet.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockSet.java?view=diff&rev=515040&r1=515039&r2=515040 ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockSet.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockSet.java Tue Mar 6 01:17:41 2007 @@ -34,7 +34,6 @@ import org.apache.derby.iapi.reference.Property; import org.apache.derby.iapi.reference.SQLState; -import java.util.Dictionary; import java.util.HashMap; import java.util.Hashtable; import java.util.Enumeration; @@ -70,7 +69,7 @@ @see LockControl */ -final class LockSet { +final class LockSet implements LockTable { /* ** Fields */ @@ -85,8 +84,8 @@
MT - immutable */ - protected int deadlockTimeout = Property.DEADLOCK_TIMEOUT_DEFAULT * 1000; - protected int waitTimeout = Property.WAIT_TIMEOUT_DEFAULT * 1000; + private int deadlockTimeout = Property.DEADLOCK_TIMEOUT_DEFAULT * 1000; + private int waitTimeout = Property.WAIT_TIMEOUT_DEFAULT * 1000; //EXCLUDE-START-lockdiag- @@ -487,7 +486,7 @@ item. */ - void unlock(Latch item, int unlockCount) { + public void unlock(Latch item, int unlockCount) { if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON(Constants.LOCK_TRACE)) { @@ -567,13 +566,148 @@ nextGrant.wakeUp(Constants.WAITING_LOCK_GRANT); } } + + /** + * Unlock an object once if it is present in the specified group. Also + * remove the object from the group. + * + * @param space the compatibility space + * @param ref a reference to the locked object + * @param qualifier qualifier of the lock + * @param group a map representing the locks in a group + * @return the corresponding lock in the group map, or null if + * the object was not unlocked + */ + public synchronized Lock unlockReference(CompatibilitySpace space, + Lockable ref, Object qualifier, + Map group) { + + Control control = getControl(ref); + if (control == null) { + return null; + } + + Lock setLock = control.getLock(space, qualifier); + if (setLock == null) { + return null; + } + + Lock lockInGroup = (Lock) group.remove(setLock); + if (lockInGroup != null) { + unlock(lockInGroup, 1); + } + + return lockInGroup; + } + + /** + * Lock an object and release the lock immediately. Equivalent to + *
+     * Lock lock = lockTable.lockObject(space, ref, qualifier, timeout);
+     * lockTable.unlock(lock, 1);
+     * 
+ * except that the implementation is more efficient. + * + * @param space the compatibility space + * @param ref a reference to the locked object + * @param qualifier qualifier of the lock + * @param timeout maximum time to wait in milliseconds + * (LockFactory.NO_WAIT means don't wait) + * @return true if the object was locked, or + * falseif the timeout was NO_WAIT and the lock + * couldn't be obtained immediately + * @exception StandardException if the lock could not be obtained + */ + public boolean zeroDurationLockObject( + CompatibilitySpace space, Lockable ref, Object qualifier, int timeout) + throws StandardException { + + if (SanityManager.DEBUG) { + if (SanityManager.DEBUG_ON(Constants.LOCK_TRACE)) { + D_LockControl.debugLock( + "Zero Duration Lock Request before Grant: ", + space, null, ref, qualifier, timeout); + if (SanityManager.DEBUG_ON(Constants.LOCK_STACK_TRACE)) { + // The following will print the stack trace of the lock + // request to the log. + Throwable t = new Throwable(); + java.io.PrintWriter istream = + SanityManager.GET_DEBUG_STREAM(); + istream.println("Stack trace of lock request:"); + t.printStackTrace(istream); + } + } + } + + // Very fast zeroDurationLockObject() for unlocked objects. + // If no entry exists in the lock manager for this reference + // then it must be unlocked. + // If the object is locked then we perform a grantable + // check, skipping over any waiters. + // If the caller wants to wait and the lock cannot + // be granted then we do the slow join the queue and + // release the lock method. + + synchronized (this) { + Control control = getControl(ref); + if (control == null) { + return true; + } + + // If we are grantable, ignoring waiting locks then + // we can also grant this request now, as skipping + // over the waiters won't block them as we release + // the lock rightway. + if (control.isGrantable(true, space, qualifier)) { + return true; + } + + // can't be granted and are not willing to wait. + if (timeout == C_LockFactory.NO_WAIT) { + return false; + } + } + + Lock lock = lockObject(space, ref, qualifier, timeout); + + if (SanityManager.DEBUG) { + if (SanityManager.DEBUG_ON(Constants.LOCK_TRACE)) { + D_LockControl.debugLock( + "Zero Lock Request Granted: ", + space, null, ref, qualifier, timeout); + } + } + + // and simply unlock it once + unlock(lock, 1); + + return true; + } + + /** + * Set the deadlock timeout. + * + * @param timeout deadlock timeout in milliseconds + */ + public void setDeadlockTimeout(int timeout) { + deadlockTimeout = timeout; + } + + /** + * Set the wait timeout. + * + * @param timeout wait timeout in milliseconds + */ + public void setWaitTimeout(int timeout) { + waitTimeout = timeout; + } /* ** Non public methods */ //EXCLUDE-START-lockdiag- - void setDeadlockTrace(boolean val) + public void setDeadlockTrace(boolean val) { // set this without synchronization deadlockTrace = val; @@ -611,11 +745,11 @@ } /** - * Add all waiters in this lock table to a Dictionary object. + * Add all waiters in this lock table to a Map object. *
* MT - must be synchronized on this LockSet object. */ - void addWaiters(Dictionary waiters) { + public void addWaiters(Map waiters) { for (Iterator it = locks.values().iterator(); it.hasNext(); ) { Control control = (Control) it.next(); control.addWaiters(waiters); @@ -623,11 +757,10 @@ } //EXCLUDE-START-lockdiag- - /* + /** * make a shallow clone of myself and my lock controls */ - /* package */ - synchronized Map shallowClone() + public synchronized Map shallowClone() { HashMap clone = new HashMap(); @@ -653,7 +786,7 @@ *
* MT - must be synchronized on this LockSet object. */ - void oneMoreWaiter() { + public void oneMoreWaiter() { blockCount++; } @@ -662,11 +795,11 @@ *
* MT - must be synchronized on this LockSet object. */ - void oneLessWaiter() { + public void oneLessWaiter() { blockCount--; } - synchronized boolean anyoneBlocked() { + public synchronized boolean anyoneBlocked() { if (SanityManager.DEBUG) { SanityManager.ASSERT( blockCount >= 0, "blockCount should not be negative"); @@ -680,7 +813,7 @@ *
* MT - must be synchronized on this LockSet object. */ - public final Control getControl(Lockable ref) { + private final Control getControl(Lockable ref) { return (Control) locks.get(ref); } } Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockSpace.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockSpace.java?view=diff&rev=515040&r1=515039&r2=515040 ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockSpace.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockSpace.java Tue Mar 6 01:17:41 2007 @@ -137,7 +137,7 @@ Unlock all the locks in a group and then remove the group. */ - synchronized void unlockGroup(LockSet lset, Object group) { + synchronized void unlockGroup(LockTable lset, Object group) { HashMap dl = (HashMap) groups.remove(group); if (dl == null) return; @@ -184,7 +184,7 @@ /** Unlock all locks in the group that match the key */ - synchronized void unlockGroup(LockSet lset, Object group, Matchable key) { + synchronized void unlockGroup(LockTable lset, Object group, Matchable key) { HashMap dl = (HashMap) groups.get(group); if (dl == null) return; // no group at all @@ -264,29 +264,17 @@ } - synchronized int unlockReference(LockSet lset, Lockable ref, Object qualifier, Object group) { + synchronized int unlockReference(LockTable lset, Lockable ref, + Object qualifier, Object group) { // look for locks matching our reference and qualifier. HashMap dl = (HashMap) groups.get(group); if (dl == null) return 0; - Lock lockInGroup; - synchronized (lset) { - Control control = lset.getControl(ref); - if (control == null) - return 0; - - Lock setLock = control.getLock(this, qualifier); - if (setLock == null) - return 0; - - lockInGroup = (Lock) dl.remove(setLock); - if (lockInGroup == null) - return 0; - setLock = null; - - lset.unlock(lockInGroup, 1); + Lock lockInGroup = lset.unlockReference(this, ref, qualifier, dl); + if (lockInGroup == null) { + return 0; } if (lockInGroup.getCount() == 1) { Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockTable.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockTable.java?view=auto&rev=515040 ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockTable.java (added) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockTable.java Tue Mar 6 01:17:41 2007 @@ -0,0 +1,152 @@ +/* + + Derby - Class org.apache.derby.impl.services.locks.LockTable + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to you 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 java.util.Map; +import org.apache.derby.iapi.error.StandardException; +import org.apache.derby.iapi.services.locks.CompatibilitySpace; +import org.apache.derby.iapi.services.locks.Latch; +import org.apache.derby.iapi.services.locks.Lockable; + +/** + * Interface which must be implemented by lock table classes. + */ +interface LockTable { + + /** + * Lock an object. + * + * @param compatibilitySpace the compatibility space + * @param ref the object to lock + * @param qualifier qualifier of the lock + * @param timeout maximum time to wait in milliseconds + * (LockFactory.NO_WAIT means don't wait) + * @return a reference to the lock, or null if the timeout was + * NO_WAIT and the lock couldn't be obtained immediately + * @exception StandardException if the lock could not be obtained + */ + Lock lockObject(CompatibilitySpace compatibilitySpace, Lockable ref, + Object qualifier, int timeout) + throws StandardException; + + /** + * Unlock an object previously locked by lockObject(). + * + * @param item the lock to unlock + * @param unlockCount the number of times to unlock the item; or zero, + * meaning take the unlock count from the item + */ + void unlock(Latch item, int unlockCount); + + /** + * Unlock an object once if it is present in the specified group. Also + * remove the object from the group. + * + * @param space the compatibility space + * @param ref a reference to the locked object + * @param qualifier qualifier of the lock + * @param group a map representing the locks in a group + * @return the corresponding lock in the group map, or null if + * the object was not unlocked + */ + Lock unlockReference(CompatibilitySpace space, Lockable ref, + Object qualifier, Map group); + + /** + * Notify the lock table that it has one more waiter. + */ + void oneMoreWaiter(); + + /** + * Notify the lock table that it has one less waiter. + * + */ + void oneLessWaiter(); + + /** + * Check whether there are anyone blocked in the lock table. + * + * @return true if someone is blocked, false + * otherwise + */ + boolean anyoneBlocked(); + + /** + * Lock an object and release the lock immediately. Equivalent to + *
+     * Lock lock = lockTable.lockObject(space, ref, qualifier, timeout);
+     * lockTable.unlock(lock, 1);
+     * 
+ * except that the implementation might be more efficient. + * + * @param space the compatibility space + * @param ref a reference to the locked object + * @param qualifier qualifier of the lock + * @param timeout maximum time to wait in milliseconds + * (LockFactory.NO_WAIT means don't wait) + * @return true if the object was locked, or + * falseif the timeout was NO_WAIT and the lock + * couldn't be obtained immediately + * @exception StandardException if the lock could not be obtained + */ + boolean zeroDurationLockObject(CompatibilitySpace space, Lockable ref, + Object qualifier, int timeout) + throws StandardException; + + /** + * Create a map containing a snapshot of all the (Lockable, + * LockControl) pairs in the lock table. + * + * @return a shallow clone of the lock table + */ + Map shallowClone(); + + /** + * Set the deadlock timeout. + * + * @param timeout deadlock timeout in milliseconds + */ + void setDeadlockTimeout(int timeout); + + /** + * Set the wait timeout. + * + * @param timeout wait timeout in milliseconds + */ + void setWaitTimeout(int timeout); + + /** + * Enable or disable tracing of deadlocks. + * + * @param flag true enables tracing, false + * disables tracing + */ + void setDeadlockTrace(boolean flag); + + /** + * Add all waiters in the lock table to the specified map. + * + * @param waiters the map to add the waiters to + * @see LockControl#addWaiters + */ + void addWaiters(Map waiters); +} Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/LockTable.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/SinglePool.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/SinglePool.java?view=diff&rev=515040&r1=515039&r2=515040 ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/SinglePool.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/locks/SinglePool.java Tue Mar 6 01:17:41 2007 @@ -58,7 +58,7 @@
MT - immutable - content dynamic : LockSet is ThreadSafe */ - protected final LockSet lockTable; + protected final LockTable lockTable; /** True if all deadlocks errors should be logged. @@ -298,68 +298,8 @@ Lockable ref, Object qualifier, int timeout) throws StandardException { - - if (SanityManager.DEBUG) { - if (SanityManager.DEBUG_ON(Constants.LOCK_TRACE)) { - - D_LockControl.debugLock("Zero Duration Lock Request before Grant: ", - compatibilitySpace, (Object) null, ref, qualifier, timeout); - - if (SanityManager.DEBUG_ON(Constants.LOCK_STACK_TRACE)) - { - // The following will print the stack trace of the lock - // request to the log. - Throwable t = new Throwable(); - java.io.PrintWriter istream = SanityManager.GET_DEBUG_STREAM(); - - istream.println("Stack trace of lock request:"); - t.printStackTrace(istream); - } - } - } - - // Very fast zeroDurationlockObject() for unlocked objects. - // If no entry exists in the lock manager for this reference - // then it must be unlocked. - // If the object is locked then we perform a grantable - // check, skipping over any waiters. - // If the caller wants to wait and the lock cannot - // be granted then we do the slow join the queue and - // release the lock method. - synchronized (lockTable) { - - Control control = lockTable.getControl(ref); - if (control == null) { - return true; - } - - // If we are grantable, ignoring waiting locks then - // we can also grant this request now, as skipping - // over the waiters won't block them as we release - // the lock rightway. - if (control.isGrantable(true, compatibilitySpace, qualifier)) - return true; - - // can't be granted and are not willing to wait. - if (timeout == C_LockFactory.NO_WAIT) - return false; - } - - Lock lock = - lockTable.lockObject(compatibilitySpace, ref, qualifier, timeout); - - if (SanityManager.DEBUG) { - if (SanityManager.DEBUG_ON(Constants.LOCK_TRACE)) { - D_LockControl.debugLock( - "Zero Lock Request Granted: ", - compatibilitySpace, (Object) null, ref, qualifier, timeout); - } - } - - // and simply unlock it once - lockTable.unlock(lock, 1); - - return true; + return lockTable.zeroDurationLockObject( + compatibilitySpace, ref, qualifier, timeout); } public boolean isLockHeld(CompatibilitySpace compatibilitySpace, @@ -458,9 +398,11 @@ String svalue = (String) value; if (key.equals(Property.DEADLOCK_TIMEOUT)) - lockTable.deadlockTimeout = getWaitValue(svalue, Property.DEADLOCK_TIMEOUT_DEFAULT); + lockTable.setDeadlockTimeout( + getWaitValue(svalue, Property.DEADLOCK_TIMEOUT_DEFAULT)); else if (key.equals(Property.LOCKWAIT_TIMEOUT)) - lockTable.waitTimeout = getWaitValue(svalue, Property.WAIT_TIMEOUT_DEFAULT); + lockTable.setWaitTimeout( + getWaitValue(svalue, Property.WAIT_TIMEOUT_DEFAULT)); else if (key.equals(Property.DEADLOCK_MONITOR)) { deadlockMonitor = PropertyUtil.booleanProperty(Property.DEADLOCK_MONITOR, svalue, false) ? StandardException.REPORT_ALWAYS : StandardException.REPORT_DEFAULT;