You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2011/10/11 14:56:09 UTC

svn commit: r1181761 - in /db/derby/code/branches/10.8: ./ java/client/org/apache/derby/client/net/NetCursor.java java/testing/org/apache/derbyTesting/functionTests/tests/store/IndexSplitDeadlockTest.java

Author: kahatlen
Date: Tue Oct 11 12:56:08 2011
New Revision: 1181761

URL: http://svn.apache.org/viewvc?rev=1181761&view=rev
Log:
DERBY-5440: test failure in testBTreeForwardScan_fetchRows_resumeAfterWait_nonUnique_split(org.apache.derbyTesting.functionTests.tests.store.IndexSplitDeadlockTest)junit.framework.AssertionFailedError: expected:<1> but was:<0>

Merged fix from trunk (revision 1181756).

Modified:
    db/derby/code/branches/10.8/   (props changed)
    db/derby/code/branches/10.8/java/client/org/apache/derby/client/net/NetCursor.java   (props changed)
    db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/store/IndexSplitDeadlockTest.java

Propchange: db/derby/code/branches/10.8/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Oct 11 12:56:08 2011
@@ -1,2 +1,2 @@
 /db/derby/code/branches/10.7:1061570,1061578,1082235
-/db/derby/code/trunk:1063809,1088633,1089795,1091000,1091221,1091285,1092067,1092795,1094315,1094572,1094728,1095247,1096741,1096890,1096991,1097247,1097249,1097460,1097469,1097471,1098033,1101059,1101839,1102620,1102826,1103681,1103718,1103742,1104365,1125305,1126358,1126468,1127825,1127883,1128243,1128942,1129136,1129764,1129797,1130077,1130084,1130632,1130895,1131030,1131272,1132546,1132664,1132747,1132860,1132928,1133304,1133317,1133741,1133752,1134139,1136363,1136371,1136397,1136844,1137213,1138201,1138341,1138444,1138787,1138795,1139449,1139451,1140222,1140744,1141924,1142583,1142635,1145057,1146644,1146915,1146962,1147219,1147242,1147335,1148344,1148354,1148429,1148658,1149054,1149090,1149270,1149482,1149662,1151101,1151612,1158108,1160593,1160597,1161208,1162737,1163131,1163616,1164358,1164370,1164495,1165221,1166313,1167017,1167226,1167470,1169692,1170470,1171227,1171665,1171672,1173446,1173647,1174436,1174646,1176633,1176636,1177589,1179374,1179546,1180790,1180858
+/db/derby/code/trunk:1063809,1088633,1089795,1091000,1091221,1091285,1092067,1092795,1094315,1094572,1094728,1095247,1096741,1096890,1096991,1097247,1097249,1097460,1097469,1097471,1098033,1101059,1101839,1102620,1102826,1103681,1103718,1103742,1104365,1125305,1126358,1126468,1127825,1127883,1128243,1128942,1129136,1129764,1129797,1130077,1130084,1130632,1130895,1131030,1131272,1132546,1132664,1132747,1132860,1132928,1133304,1133317,1133741,1133752,1134139,1136363,1136371,1136397,1136844,1137213,1138201,1138341,1138444,1138787,1138795,1139449,1139451,1140222,1140744,1141924,1142583,1142635,1145057,1146644,1146915,1146962,1147219,1147242,1147335,1148344,1148354,1148429,1148658,1149054,1149090,1149270,1149482,1149662,1151101,1151612,1158108,1160593,1160597,1161208,1162737,1163131,1163616,1164358,1164370,1164495,1165221,1166313,1167017,1167226,1167470,1169692,1170470,1171227,1171665,1171672,1173446,1173647,1174436,1174646,1176633,1176636,1177589,1179374,1179546,1180790,1180858,
 1181756

Propchange: db/derby/code/branches/10.8/java/client/org/apache/derby/client/net/NetCursor.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Oct 11 12:56:08 2011
@@ -1,2 +1,2 @@
 /db/derby/code/branches/10.7/java/client/org/apache/derby/client/net/NetCursor.java:1061570,1061578,1082235
-/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java:1063809,1088633,1089795,1091000,1091221,1091285,1092067,1092795,1094315,1094572,1094728,1095247,1096741,1096890,1096991,1097247,1097249,1097460,1097469,1097471,1098033,1101059,1101839,1102620,1102826,1103681,1103718,1103742,1104365,1125305,1126358,1126468,1127825,1127883,1128243,1128942,1129136,1129764,1129797,1130077,1130084,1130632,1130895,1131030,1131272,1132546,1132664,1132747,1132860,1132928,1133304,1133317,1133741,1133752,1134139,1136363,1136371,1136397,1136844,1137213,1138201,1138341,1138444,1138787,1138795,1139449,1139451,1140222,1140744,1141924,1142583,1142635,1145057,1145961,1146644,1146915,1146962,1147219,1147242,1147335,1148344,1148354,1148429,1148658,1149054,1149090,1149270,1149482,1149662,1151101,1151612,1158108,1160593,1160597,1161208,1162737,1163131,1163616,1164358,1164370,1164495,1165221,1167017,1167470,1169692,1171665,1171672,1173647,1174436,1176633,1176636,1177589,1179374,1179546,1
 180790,1180858
+/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java:1063809,1088633,1089795,1091000,1091221,1091285,1092067,1092795,1094315,1094572,1094728,1095247,1096741,1096890,1096991,1097247,1097249,1097460,1097469,1097471,1098033,1101059,1101839,1102620,1102826,1103681,1103718,1103742,1104365,1125305,1126358,1126468,1127825,1127883,1128243,1128942,1129136,1129764,1129797,1130077,1130084,1130632,1130895,1131030,1131272,1132546,1132664,1132747,1132860,1132928,1133304,1133317,1133741,1133752,1134139,1136363,1136371,1136397,1136844,1137213,1138201,1138341,1138444,1138787,1138795,1139449,1139451,1140222,1140744,1141924,1142583,1142635,1145057,1145961,1146644,1146915,1146962,1147219,1147242,1147335,1148344,1148354,1148429,1148658,1149054,1149090,1149270,1149482,1149662,1151101,1151612,1158108,1160593,1160597,1161208,1162737,1163131,1163616,1164358,1164370,1164495,1165221,1167017,1167470,1169692,1171665,1171672,1173647,1174436,1176633,1176636,1177589,1179374,1179546,1
 180790,1180858,1181756

Modified: db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/store/IndexSplitDeadlockTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/store/IndexSplitDeadlockTest.java?rev=1181761&r1=1181760&r2=1181761&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/store/IndexSplitDeadlockTest.java (original)
+++ db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/store/IndexSplitDeadlockTest.java Tue Oct 11 12:56:08 2011
@@ -360,11 +360,12 @@ public class IndexSplitDeadlockTest exte
         commit();
 
         // Object used for synchronization between the main thread and the
-        // helper thread. The main thread should increment the value to tell
-        // the helper thread that it's ready to start the index scan. The
-        // helper thread should increment it to tell the main thread that it
-        // has locked row 40 and is ready to insert more values.
-        final int[] syncObject = new int[1];
+        // helper thread. The main thread uses it to tell the helper thread
+        // that it has started the index scan. The helper thread uses it
+        // to tell the main thread that it has locked row 40 and is ready to
+        // insert more values. Both threads should wait until the other thread
+        // has reached the barrier before continuing.
+        final Barrier barrier = new Barrier(2);
 
         // Lock a row on the first page in a different thread to stop the
         // index scan. Then split the first leaf by inserting many values
@@ -376,20 +377,12 @@ public class IndexSplitDeadlockTest exte
                 s.executeUpdate("update t set x = x where x = 40");
                 s.close();
 
-                synchronized (syncObject) {
-                    // Tell the main thread that we've locked the row and that
-                    // it can go ahead with the index scan.
-                    syncObject[0]++;
-                    syncObject.notifyAll();
-
-                    // Wait here until the main thread is actually ready to
-                    // start the scan.
-                    while (syncObject[0] < 2) {
-                        syncObject.wait();
-                    }
-                }
+                // Tell the main thread that we've locked the row and that
+                // it can go ahead with the index scan. Wait here until the
+                // main thread has started the scan.
+                barrier.await();
 
-                // The main thread is ready to start the index scan. Give it a
+                // The main thread has started the index scan. Give it a
                 // second to get to the row we have locked.
                 Thread.sleep(1000L);
 
@@ -406,26 +399,21 @@ public class IndexSplitDeadlockTest exte
         });
 
         // Prepare the index scan.
-        PreparedStatement scan = prepareStatement(
+        ResultSet rs = s.executeQuery(
                 "select * from t --DERBY-PROPERTIES constraint=C");
 
-        synchronized (syncObject) {
-            // Tell the helper thread we're ready to start the scan.
-            syncObject[0]++;
-            syncObject.notifyAll();
-
-            // Wait until the helper thread has obtained the lock.
-            while (syncObject[0] < 2) {
-                syncObject.wait();
-            }
-        }
-
         // Perform an index scan. Will be blocked for a while when fetching
         // the row where x=40, but should be able to resume the scan.
-        ResultSet rs = scan.executeQuery();
         for (int i = 0; i < 300; i++) {
             assertTrue(rs.next());
             assertEquals(i, rs.getInt(1));
+
+            // Once we have fetched the first row, tell the helper thread we
+            // have started the index scan, and wait until it has locked the
+            // row that should block the scan (x=40).
+            if (i == 0) {
+                barrier.await();
+            }
         }
         assertFalse(rs.next());
         rs.close();
@@ -492,6 +480,11 @@ public class IndexSplitDeadlockTest exte
         }
         commit();
 
+        // Object used for synchronization between main thread and helper
+        // thread. They should both wait for the other thread to reach the
+        // barrier point before continuing.
+        final Barrier barrier = new Barrier(2);
+
         // Hold a lock in a different thread to stop the index scan, then
         // split the first leaf (on which the scan is positioned) before the
         // lock is released.
@@ -500,30 +493,42 @@ public class IndexSplitDeadlockTest exte
                 conn.setAutoCommit(false);
                 Statement s = conn.createStatement();
                 s.executeUpdate("update t set x = x where x = 40");
-                // Give the index scan time to start and position on
-                // the row we have locked. (Give it two seconds, since the
-                // main thread sleeps for one second first before it starts
-                // the index scan.)
-                Thread.sleep(2000);
-                // Split the first leaf by inserting more zeros
-                for (int i = -1; i > -300; i--) {
-                    s.executeUpdate("insert into t values 0");
+
+                // Tell the main thread we have locked the row, and wait for
+                // it to start the index scan.
+                barrier.await();
+
+                // Give the index scan time to get to the row we have locked.
+                Thread.sleep(1000);
+
+                // The index scan should be blocked now. Split the first leaf
+                // by inserting more values just before the lowest key, so
+                // that we can verify that the index scan is able to reposition
+                // correctly after a page split.
+                for (int i = 0; i < 300; i++) {
+                    s.executeUpdate("insert into t values -1");
                 }
                 s.close();
                 conn.commit();
             }
         });
 
-        // Give the other thread time to obtain the lock
-        Thread.sleep(1000);
-
         // Perform an index scan. Will be blocked for a while when fetching
-        // the row where x=100, but should be able to resume the scan.
+        // the row where x=40, but should be able to resume the scan after
+        // the helper thread commits and releases its locks.
         ResultSet rs = s.executeQuery(
                 "select * from t --DERBY-PROPERTIES index=IDX");
+
         for (int i = 0; i < 300; i++) {
             assertTrue(rs.next());
             assertEquals(i, rs.getInt(1));
+
+            // Once we have fetched the first row, tell the helper thread we
+            // have started the index scan, and wait until it has locked the
+            // row that should block the scan (x=40).
+            if (i == 0) {
+                barrier.await();
+            }
         }
         assertFalse(rs.next());
         rs.close();
@@ -829,4 +834,38 @@ public class IndexSplitDeadlockTest exte
             }
         }
     }
+
+    /**
+     * A poor man's substitute for java.util.concurrent.CyclicBarrier.
+     */
+    private static class Barrier {
+        /** The number of parties that still haven't reached the barrier. */
+        private int n;
+
+        /**
+         * Create a barrier that blocks until the specified number of threads
+         * have reached the barrier point.
+         *
+         * @param parties the number of parties to wait for at the barrier
+         */
+        Barrier(int parties) {
+            n = parties;
+        }
+
+        /**
+         * Wait until all parties have reached the barrier.
+         *
+         * @throws InterruptedException if the thread is interrupted
+         */
+        synchronized void await() throws InterruptedException {
+            assertTrue("Too many parties at barrier", n > 0);
+
+            n--;
+            notifyAll();
+
+            while (n > 0) {
+                wait();
+            }
+        }
+    }
 }