db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mi...@apache.org
Subject svn commit: r353812 - in /db/derby/code/branches/10.1/java: engine/org/apache/derby/impl/services/locks/ testing/org/apache/derbyTesting/functionTests/master/ testing/org/apache/derbyTesting/functionTests/suites/ testing/org/apache/derbyTesting/functio...
Date Sun, 04 Dec 2005 04:37:43 GMT
Author: mikem
Date: Sat Dec  3 20:37:39 2005
New Revision: 353812

URL: http://svn.apache.org/viewcvs?rev=353812&view=rev
Log:
merging fix for DERBY-715 from trunk to 10.1 branch.

Sometimes (timing dependent) a lock deadlock was incorrectly returned to the
user as a lock timeout.  The code in LockSet was using the wrong variable
to determine if a deadlock had been detected, that variable sometimes was
right and sometimes wrong.  Changed all the code to use the direct return
from the deadlock detection routine.  Added a test that causes 5 deadlocks,
previous to the fix this test would always report at least 1 timeout on
my single processor, windows xp, laptop.


Added:
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/st_derby715.out
      - copied unchanged from r351543, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/st_derby715.out
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/st_derby715.java
      - copied unchanged from r351543, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/st_derby715.java
Modified:
    db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/locks/LockSet.java
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storetests.runall
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/BaseTest.java
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/copyfiles.ant

Modified: db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/locks/LockSet.java
URL: http://svn.apache.org/viewcvs/db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/locks/LockSet.java?rev=353812&r1=353811&r2=353812&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/locks/LockSet.java
(original)
+++ db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/locks/LockSet.java
Sat Dec  3 20:37:39 2005
@@ -217,7 +217,7 @@
 		{
 			// always check for deadlocks as there should not be any
 			deadlockWait = true;
-			if ((actualTimeout = deadlockTimeout) == C_LockFactory.WAIT_FOREVER) 
+			if ((actualTimeout = deadlockTimeout) == C_LockFactory.WAIT_FOREVER)
 				actualTimeout = Property.DEADLOCK_TIMEOUT_DEFAULT * 1000;
 		}
 		else
@@ -230,11 +230,18 @@
 
 
 			// five posible cases
-			// i)   timeout -1, deadlock -1 -> just wait forever, no deadlock check
-			// ii)  timeout >= 0, deadlock -1 -> just wait for timeout, no deadlock check
-			// iii) timeout -1, deadlock >= 0 -> wait for deadlock, then deadlock check, then
infinite timeout
-			// iv)  timeout >=0, deadlock < timeout -> wait for deadlock, then deadlock check,
then wait for (timeout - deadlock)
-			// v)   timeout >=0, deadlock >= timeout -> just wait for timeout, no deadlock
check
+			// i)   timeout -1, deadlock -1         -> 
+            //          just wait forever, no deadlock check
+			// ii)  timeout >= 0, deadlock -1       -> 
+            //          just wait for timeout, no deadlock check
+			// iii) timeout -1, deadlock >= 0       -> 
+            //          wait for deadlock, then deadlock check, 
+            //          then infinite timeout
+			// iv)  timeout >=0, deadlock < timeout -> 
+            //          wait for deadlock, then deadlock check, 
+            //          then wait for (timeout - deadlock)
+			// v)   timeout >=0, deadlock >= timeout -> 
+            //          just wait for timeout, no deadlock check
 
 
 			if (deadlockTimeout >= 0) {
@@ -257,212 +264,239 @@
 		}
 
 
-			ActiveLock waitingLock = (ActiveLock) lockItem;
-			lockItem = null;
+        ActiveLock waitingLock = (ActiveLock) lockItem;
+        lockItem = null;
 
-			if (deadlockTrace)
-			{
-				// we want to keep a stack trace of this thread just before it goes
-				// into wait state, no need to synchronized because Hashtable.put
-				// is synchronized and the new throwable is local to this thread.
-				lockTraces.put(waitingLock, new Throwable());
-			}
+        if (deadlockTrace)
+        {
+            // we want to keep a stack trace of this thread just before it goes
+            // into wait state, no need to synchronized because Hashtable.put
+            // is synchronized and the new throwable is local to this thread.
+            lockTraces.put(waitingLock, new Throwable());
+        }
 
-			int earlyWakeupCount = 0;
-			long startWaitTime = 0;
+        int earlyWakeupCount = 0;
+        long startWaitTime = 0;
 
 		try {
 forever:	for (;;) {
 
+                byte wakeupReason = waitingLock.waitForGrant(actualTimeout);
+                
+                ActiveLock nextWaitingLock = null;
+                Object[] deadlockData = null;
+
+                try {
+                    boolean willQuitWait;
+                    Enumeration timeoutLockTable = null;
+                    long currentTime = 0;
+        
+                    synchronized (this) {
+
+                        if (control.isGrantable(
+                                control.firstWaiter() == waitingLock,
+                                compatabilitySpace, 
+                                qualifier)) {
+
+                            // Yes, we are granted, put us on the granted queue.
+                            control.grant(waitingLock);
+
+                            // Remove from the waiting queue & get next waiter
+                            nextWaitingLock = 
+                                control.getNextWaiter(waitingLock, true, this);
+
+                            // this is where we need to re-obtain the latch, 
+                            // it's safe to call this lockObject() which will 
+                            // get the synchronization we already hold, because
+                            // java allows nested synchronization and it will 
+                            // be released automatically if we have to wait
+
+                            if (latch != null) {
+                                lockObject(
+                                    compatabilitySpace, latch.getLockable(), 
+                                    latch.getQualifier(), 
+                                    C_LockFactory.WAIT_FOREVER,
+                                    (Latch) null);
+                            }
+                            return waitingLock;
+                        }
 
-			byte wakeupReason = waitingLock.waitForGrant(actualTimeout);
-			
-			ActiveLock nextWaitingLock = null;
-			Object[] deadlockData = null;
+                        // try again later
+                        waitingLock.clearPotentiallyGranted(); 
 
-			try {
-				boolean willQuitWait;
-                Enumeration timeoutLockTable = null;
-                long currentTime = 0;
-	
-				synchronized (this) {
+                        willQuitWait = 
+                            (wakeupReason != Constants.WAITING_LOCK_GRANT);
 
-					if (control.isGrantable(control.firstWaiter() == waitingLock,
-							compatabilitySpace, qualifier)) {
+                        StandardException deadlockException = null;
 
-						// Yes, we are granted, put us on the granted queue.
-						control.grant(waitingLock);
+                        if (((wakeupReason == Constants.WAITING_LOCK_IN_WAIT) &&
+                                    deadlockWait) ||
+                            (wakeupReason == Constants.WAITING_LOCK_DEADLOCK))
+                        {
 
-						// Remove from the waiting queue & get next waiter
-						nextWaitingLock = control.getNextWaiter(waitingLock, true, this);
-
-						// this is where we need to re-obtain the latch, it's 
-						// safe to call this lockObject() which will get the 
-						// synchronization we already hold, because java allows
-						// nested synchronization and it will be released 
-						// automatically if we have to wait
-						if (latch != null) {
-							lockObject(
-								compatabilitySpace, latch.getLockable(), 
-								latch.getQualifier(), C_LockFactory.WAIT_FOREVER,
-								(Latch) null);
-						}
-						return waitingLock;
-					}
-
-					waitingLock.clearPotentiallyGranted(); // try again later
-
-					willQuitWait = (wakeupReason != Constants.WAITING_LOCK_GRANT);
-
-					StandardException deadlockException = null;
-
-					if (((wakeupReason == Constants.WAITING_LOCK_IN_WAIT) && deadlockWait) ||
-						(wakeupReason == Constants.WAITING_LOCK_DEADLOCK))
-					{
-
-						// check for a deadlock, even if we were woken up to because
-						// we were selected as a victim we still check because the situation
-						// may have changed.
-						deadlockData = Deadlock.look(factory, this, control, waitingLock, wakeupReason);
-						if (deadlockData == null) {
-							// we don't have a deadlock
-							deadlockWait = false;
-
-							actualTimeout = timeout;
-							startWaitTime = 0;
-							willQuitWait = false;
-						} else {
-							willQuitWait = true;
-						}
-					}
-
-					nextWaitingLock = control.getNextWaiter(waitingLock, willQuitWait, this);
-
-
-					// If we were not woken by another then we have
-					// timed out. Either deadlock out or timeout
-					if (willQuitWait) {
-
-						// Even if we deadlocked trying to get the lock, still 
-                        // reget the latch so that client's need not know 
-                        // latch was released.
-
-						if (latch != null) {
-							lockObject(
-								compatabilitySpace, latch.getLockable(), 
-								latch.getQualifier(), C_LockFactory.WAIT_FOREVER,
-								(Latch) null);
-						}
+                            // check for a deadlock, even if we were woken up 
+                            // because we were selected as a victim we still 
+                            // check because the situation may have changed.
+                            deadlockData = 
+                                Deadlock.look(
+                                    factory, this, control, waitingLock, 
+                                    wakeupReason);
+
+                            if (deadlockData == null) {
+                                // we don't have a deadlock
+                                deadlockWait = false;
+
+                                actualTimeout = timeout;
+                                startWaitTime = 0;
+                                willQuitWait = false;
+                            } else {
+                                willQuitWait = true;
+                            }
+                        }
 
-                        if (SanityManager.DEBUG) 
-                        {
-                            if (SanityManager.DEBUG_ON("DeadlockTrace"))
+                        nextWaitingLock = 
+                            control.getNextWaiter(
+                                waitingLock, willQuitWait, this);
+
+
+                        // If we were not woken by another then we have
+                        // timed out. Either deadlock out or timeout
+                        if (willQuitWait) {
+
+                            // Even if we deadlocked trying to get the lock, 
+                            // still reget the latch so that client's need not
+                            // know latch was released.
+
+                            if (latch != null) {
+                                lockObject(
+                                    compatabilitySpace, latch.getLockable(), 
+                                    latch.getQualifier(), 
+                                    C_LockFactory.WAIT_FOREVER, (Latch) null);
+                            }
+
+                            if (SanityManager.DEBUG) 
                             {
+                                if (SanityManager.DEBUG_ON("DeadlockTrace"))
+                                {
 
-                                SanityManager.showTrace(new Throwable());
+                                    SanityManager.showTrace(new Throwable());
 
-                                // The following dumps the lock table as it 
-                                // exists at the time a timeout is about to 
-                                // cause a deadlock exception to be thrown.
+                                    // The following dumps the lock table as it 
+                                    // exists at the time a timeout is about to 
+                                    // cause a deadlock exception to be thrown.
 
-                                lockDebug = 
+                                    lockDebug = 
                                     DiagnosticUtil.toDiagString(waitingLock)   +
                                     "\nGot deadlock/timeout, here's the table" +
                                     this.toDebugString();
+                                }
                             }
-                        }
-                        
-                        if(!deadlockWait)
-                        {
-                            if( deadlockTrace )
-                            {   // want a copy of the LockTable and the time
+                            
+                            if (deadlockTrace && (deadlockData == null))
+                            {
+                                // if ending lock request due to lock timeout
+                                // want a copy of the LockTable and the time,
+                                // in case of deadlock deadlockData has the
+                                // info we need.
                                 currentTime = System.currentTimeMillis(); 
-                                timeoutLockTable = factory.makeVirtualLockTable();
+                                timeoutLockTable = 
+                                    factory.makeVirtualLockTable();
                             }
                         }
-					}
 
-				} // synchronized block
+                    } // synchronized block
 
-				// need to do this outside of the synchronized block as the
-                // message text building (timeouts and deadlocks) may involve
-                // getting locks to look up table names from identifiers.
-                if (willQuitWait)
-                {
-                    if (SanityManager.DEBUG)
+                    // need to do this outside of the synchronized block as the
+                    // message text building (timeouts and deadlocks) may 
+                    // involve getting locks to look up table names from 
+                    // identifiers.
+
+                    if (willQuitWait)
                     {
-                        if (lockDebug != null)
+                        if (SanityManager.DEBUG)
                         {
-                            String type = 
-                                (deadlockWait ? "deadlock:" : "timeout:"); 
+                            if (lockDebug != null)
+                            {
+                                String type = 
+                                    ((deadlockData != null) ? 
+                                         "deadlock:" : "timeout:"); 
+
+                                SanityManager.DEBUG_PRINT(
+                                    type,
+                                    "wait on lockitem caused " + type + 
+                                    lockDebug);
+                            }
 
-                            SanityManager.DEBUG_PRINT(
-                                type,
-                                "wait on lockitem caused " + type + lockDebug);
                         }
 
-                    }
+                        if (deadlockData == null)
+                        {
+                            // ending wait because of lock timeout.
 
-                    if(!deadlockWait)
-                    {
-                        if( deadlockTrace )
-                        {   //Turn ON derby.locks.deadlockTrace to build the lockTable.
-                            throw Timeout.buildException(waitingLock, timeoutLockTable, currentTime);
+                            if (deadlockTrace)
+                            {   
+                                // Turn ON derby.locks.deadlockTrace to build 
+                                // the lockTable.
+                                    
+                                
+                                throw Timeout.buildException(
+                                    waitingLock, timeoutLockTable, currentTime);
+                            }
+                            else
+                            {
+                                StandardException se = 
+                                    StandardException.newException(
+                                        SQLState.LOCK_TIMEOUT);
+
+                                throw se;
+                            }
                         }
-                        else
+                        else 
                         {
-			                StandardException se = 
-                                StandardException.newException(
-                                    SQLState.LOCK_TIMEOUT);
+                            // ending wait because of lock deadlock.
 
-			                throw se;
+                            throw Deadlock.buildException(
+                                    factory, deadlockData);
                         }
                     }
-					if (deadlockData != null) {
-						throw Deadlock.buildException(factory, deadlockData);
-					}
+                } finally {
+                    if (nextWaitingLock != null) {
+                        nextWaitingLock.wakeUp(Constants.WAITING_LOCK_GRANT);
+                        nextWaitingLock = null;
+                    }
                 }
-                    
 
-			} finally {
-				if (nextWaitingLock != null) {
-					nextWaitingLock.wakeUp(Constants.WAITING_LOCK_GRANT);
-					nextWaitingLock = null;
-				}
-
-			}
+                if (actualTimeout != C_LockFactory.WAIT_FOREVER) {
 
-			if (actualTimeout != C_LockFactory.WAIT_FOREVER) {
+                    if (wakeupReason != Constants.WAITING_LOCK_IN_WAIT)
+                        earlyWakeupCount++;
 
-				if (wakeupReason != Constants.WAITING_LOCK_IN_WAIT)
-					earlyWakeupCount++;
+                    if (earlyWakeupCount > 5) {
 
-				if (earlyWakeupCount > 5) {
+                        long now = System.currentTimeMillis();
 
-					long now = System.currentTimeMillis();
+                        if (startWaitTime != 0) {
 
-					if (startWaitTime != 0) {
+                            long sleepTime = now - startWaitTime;
 
-						long sleepTime = now - startWaitTime;
-
-						actualTimeout -= sleepTime;
-					}
+                            actualTimeout -= sleepTime;
+                        }
 
-					startWaitTime = now;
-				}
-			}
+                        startWaitTime = now;
+                    }
+                }
 
 
-		} // for(;;)
-	} finally {
-		if (deadlockTrace)
-		{
-				// I am out of the wait state, either I got my lock or I am the
-				// one who is going to detect the deadlock, don't need the
-				// stack trace anymore.
-				lockTraces.remove(waitingLock);
-		}
-	}
+            } // for(;;)
+        } finally {
+            if (deadlockTrace)
+            {
+                    // I am out of the wait state, either I got my lock or I 
+                    // am the one who is going to detect the deadlock, don't 
+                    // need the stack trace anymore.
+                    lockTraces.remove(waitingLock);
+            }
+        }
 	}
 
 	/**
@@ -565,7 +599,9 @@
 		deadlockTrace = val;
 
 		if (val && lockTraces == null)
+        {
 			lockTraces = new Hashtable();
+        }
 		else if (!val && lockTraces != null)
 		{
 			lockTraces = null;

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storetests.runall
URL: http://svn.apache.org/viewcvs/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storetests.runall?rev=353812&r1=353811&r2=353812&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storetests.runall
(original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storetests.runall
Sat Dec  3 20:37:39 2005
@@ -1,4 +1,5 @@
 storetests/st_schema.sql
+storetests/st_derby715.java
 storetests/st_1.sql
 storetests/st_b5772.sql
 storetests/derby94.sql

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/BaseTest.java
URL: http://svn.apache.org/viewcvs/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/BaseTest.java?rev=353812&r1=353811&r2=353812&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/BaseTest.java
(original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/BaseTest.java
Sat Dec  3 20:37:39 2005
@@ -45,7 +45,7 @@
 {
     private static boolean debug_system_procedures_created = false;
 
-    abstract void testList(Connection conn) throws SQLException;
+    abstract public void testList(Connection conn) throws SQLException;
 
     void runTests(String[] argv)
         throws Throwable

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/copyfiles.ant
URL: http://svn.apache.org/viewcvs/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/copyfiles.ant?rev=353812&r1=353811&r2=353812&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/copyfiles.ant
(original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/copyfiles.ant
Sat Dec  3 20:37:39 2005
@@ -10,3 +10,4 @@
 derby94_app.properties
 derby94_derby.properties
 onlineCompressTable.sql
+derby94_derby.properties



Mime
View raw message