ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java
(Generate patch)

Comparing jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java (file contents):
Revision 1.54 by jsr166, Sun May 14 02:16:56 2017 UTC vs.
Revision 1.59 by jsr166, Mon Nov 27 03:25:42 2017 UTC

# Line 9 | Line 9
9   import static java.util.concurrent.TimeUnit.MILLISECONDS;
10   import static java.util.concurrent.TimeUnit.NANOSECONDS;
11  
12 + import java.util.ArrayList;
13   import java.util.Arrays;
14   import java.util.Collection;
15   import java.util.HashSet;
# Line 19 | Line 20 | import junit.framework.AssertionFailedEr
20   import junit.framework.Test;
21   import junit.framework.TestSuite;
22  
23 + @SuppressWarnings("WaitNotInLoop") // we implement spurious-wakeup freedom
24   public class AbstractQueuedSynchronizerTest extends JSR166TestCase {
25      public static void main(String[] args) {
26          main(suite(), args);
# Line 33 | Line 35 | public class AbstractQueuedSynchronizerT
35       * methods/features of AbstractQueuedSynchronizer are tested via
36       * other test classes, including those for ReentrantLock,
37       * ReentrantReadWriteLock, and Semaphore.
38 +     *
39 +     * Unlike the javadoc sample, we don't track owner thread via
40 +     * AbstractOwnableSynchronizer methods.
41       */
42      static class Mutex extends AbstractQueuedSynchronizer {
43          /** An eccentric value for locked synchronizer state. */
# Line 40 | Line 45 | public class AbstractQueuedSynchronizerT
45  
46          static final int UNLOCKED = 0;
47  
48 +        /** Owner thread is untracked, so this is really just isLocked(). */
49          @Override public boolean isHeldExclusively() {
50              int state = getState();
51              assertTrue(state == UNLOCKED || state == LOCKED);
52              return state == LOCKED;
53          }
54  
55 <        @Override public boolean tryAcquire(int acquires) {
55 >        @Override protected boolean tryAcquire(int acquires) {
56              assertEquals(LOCKED, acquires);
57              return compareAndSetState(UNLOCKED, LOCKED);
58          }
59  
60 <        @Override public boolean tryRelease(int releases) {
60 >        @Override protected boolean tryRelease(int releases) {
61              if (getState() != LOCKED) throw new IllegalMonitorStateException();
62              assertEquals(LOCKED, releases);
63              setState(UNLOCKED);
# Line 82 | Line 88 | public class AbstractQueuedSynchronizerT
88              release(LOCKED);
89          }
90  
91 +        /** Faux-Implements Lock.newCondition(). */
92          public ConditionObject newCondition() {
93              return new ConditionObject();
94          }
95      }
96  
97      /**
98 <     * A simple latch class, to test shared mode.
98 >     * A minimal latch class, to test shared mode.
99       */
100      static class BooleanLatch extends AbstractQueuedSynchronizer {
101          public boolean isSignalled() { return getState() != 0; }
# Line 1134 | Line 1141 | public class AbstractQueuedSynchronizerT
1141  
1142          waitForQueuedThread(l, t);
1143          assertFalse(l.isSignalled());
1144 <        assertThreadStaysAlive(t);
1144 >        assertThreadBlocks(t, Thread.State.WAITING);
1145          assertHasSharedQueuedThreads(l, t);
1146          assertTrue(l.releaseShared(0));
1147          assertTrue(l.isSignalled());
# Line 1159 | Line 1166 | public class AbstractQueuedSynchronizerT
1166  
1167          waitForQueuedThread(l, t);
1168          assertFalse(l.isSignalled());
1169 <        assertThreadStaysAlive(t);
1169 >        assertThreadBlocks(t, Thread.State.TIMED_WAITING);
1170          assertTrue(l.releaseShared(0));
1171          assertTrue(l.isSignalled());
1172          awaitTermination(t);
# Line 1253 | Line 1260 | public class AbstractQueuedSynchronizerT
1260          sync.release();
1261      }
1262  
1263 +    /**
1264 +     * Disabled demo test for (unfixed as of 2017-11)
1265 +     * JDK-8191483: AbstractQueuedSynchronizer cancel/cancel race
1266 +     * ant -Djsr166.tckTestClass=AbstractQueuedSynchronizerTest -Djsr166.methodFilter=testCancelCancelRace -Djsr166.runsPerTest=100 tck
1267 +     */
1268 +    public void XXXXtestCancelCancelRace() throws InterruptedException {
1269 +        class Sync extends AbstractQueuedSynchronizer {
1270 +            private static final long serialVersionUID = 1L;
1271 +
1272 +            public boolean tryAcquire(int acquires) {
1273 +                return !hasQueuedPredecessors() && compareAndSetState(0, 1);
1274 +            }
1275 +
1276 +            protected boolean tryRelease(int releases) {
1277 +                return compareAndSetState(1, 0);
1278 +            }
1279 +        }
1280 +
1281 +        Sync s = new Sync();
1282 +        s.acquire(1);           // acquire to force other threads to enqueue
1283 +
1284 +        // try to trigger double cancel race with two background threads
1285 +        ArrayList<Thread> ts = new ArrayList<>();
1286 +        Runnable failedAcquire = () -> {
1287 +            try {
1288 +                s.acquireInterruptibly(1);
1289 +                throw new AssertionError();
1290 +            } catch (InterruptedException expected) {}
1291 +        };
1292 +        for (int i = 0; i < 2; i++) {
1293 +            Thread t = new Thread(failedAcquire);
1294 +            t.start();
1295 +            ts.add(t);
1296 +        }
1297 +        Thread.sleep(100);
1298 +        for (Thread t : ts) t.interrupt();
1299 +        for (Thread t : ts) t.join();
1300 +
1301 +        s.release(1);
1302 +
1303 +        // no one holds lock now, we should be able to acquire
1304 +        if (!s.tryAcquire(1))
1305 +            throw new RuntimeException(
1306 +                String.format(
1307 +                    "Broken: hasQueuedPredecessors=%s hasQueuedThreads=%s queueLength=%d firstQueuedThread=%s",
1308 +                    s.hasQueuedPredecessors(),
1309 +                    s.hasQueuedThreads(),
1310 +                    s.getQueueLength(),
1311 +                    s.getFirstQueuedThread()));
1312 +    }
1313 +
1314   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines