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.49 by jsr166, Sun Feb 22 04:34:44 2015 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 <        junit.textui.TestRunner.run(suite());
26 >        main(suite(), args);
27      }
28      public static Test suite() {
29          return new TestSuite(AbstractQueuedSynchronizerTest.class);
# 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 238 | Line 245 | public class AbstractQueuedSynchronizerT
245       * default timeout duration).
246       */
247      void assertAwaitTimesOut(ConditionObject c, AwaitMethod awaitMethod) {
248 <        long timeoutMillis = timeoutMillis();
249 <        long startTime = System.nanoTime();
248 >        final long timeoutMillis = timeoutMillis();
249 >        final long startTime;
250          try {
251              switch (awaitMethod) {
252              case awaitTimed:
253 +                startTime = System.nanoTime();
254                  assertFalse(c.await(timeoutMillis, MILLISECONDS));
255 +                assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
256                  break;
257              case awaitNanos:
258 +                startTime = System.nanoTime();
259                  long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
260                  long nanosRemaining = c.awaitNanos(nanosTimeout);
261                  assertTrue(nanosRemaining <= 0);
262 +                assertTrue(nanosRemaining > -MILLISECONDS.toNanos(LONG_DELAY_MS));
263 +                assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
264                  break;
265              case awaitUntil:
266 +                // We shouldn't assume that nanoTime and currentTimeMillis
267 +                // use the same time source, so don't use nanoTime here.
268 +                java.util.Date delayedDate = delayedDate(timeoutMillis);
269                  assertFalse(c.awaitUntil(delayedDate(timeoutMillis)));
270 +                assertTrue(new java.util.Date().getTime() >= delayedDate.getTime());
271                  break;
272              default:
273                  throw new UnsupportedOperationException();
274              }
275          } catch (InterruptedException ie) { threadUnexpectedException(ie); }
260        assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
276      }
277  
278      /**
# Line 960 | Line 975 | public class AbstractQueuedSynchronizerT
975       */
976      public void testAwaitUninterruptibly() {
977          final Mutex sync = new Mutex();
978 <        final ConditionObject c = sync.newCondition();
978 >        final ConditionObject condition = sync.newCondition();
979          final BooleanLatch pleaseInterrupt = new BooleanLatch();
980          Thread t = newStartedThread(new CheckedRunnable() {
981              public void realRun() {
982                  sync.acquire();
983                  assertTrue(pleaseInterrupt.releaseShared(0));
984 <                c.awaitUninterruptibly();
984 >                condition.awaitUninterruptibly();
985                  assertTrue(Thread.interrupted());
986 <                assertHasWaitersLocked(sync, c, NO_THREADS);
986 >                assertHasWaitersLocked(sync, condition, NO_THREADS);
987                  sync.release();
988              }});
989  
990          pleaseInterrupt.acquireShared(0);
991          sync.acquire();
992 <        assertHasWaitersLocked(sync, c, t);
992 >        assertHasWaitersLocked(sync, condition, t);
993          sync.release();
994          t.interrupt();
995 <        assertHasWaitersUnlocked(sync, c, t);
996 <        assertThreadStaysAlive(t);
995 >        assertHasWaitersUnlocked(sync, condition, t);
996 >        assertThreadBlocks(t, Thread.State.WAITING);
997          sync.acquire();
998 <        assertHasWaitersLocked(sync, c, t);
998 >        assertHasWaitersLocked(sync, condition, t);
999          assertHasExclusiveQueuedThreads(sync, NO_THREADS);
1000 <        c.signal();
1001 <        assertHasWaitersLocked(sync, c, NO_THREADS);
1000 >        condition.signal();
1001 >        assertHasWaitersLocked(sync, condition, NO_THREADS);
1002          assertHasExclusiveQueuedThreads(sync, t);
1003          sync.release();
1004          awaitTermination(t);
# Line 1126 | 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 1151 | 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 1245 | 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