--- jsr166/src/test/tck/StampedLockTest.java 2016/06/07 23:28:30 1.24 +++ jsr166/src/test/tck/StampedLockTest.java 2016/07/17 02:30:53 1.25 @@ -5,11 +5,18 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ +import static java.util.concurrent.TimeUnit.DAYS; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.StampedLock; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Function; import junit.framework.Test; import junit.framework.TestSuite; @@ -1051,4 +1058,53 @@ public class StampedLockTest extends JSR assertThrows(IllegalMonitorStateException.class, actions); } + static long writeLockInterruptiblyUninterrupted(StampedLock sl) { + try { return sl.writeLockInterruptibly(); } + catch (InterruptedException ex) { throw new AssertionError(ex); } + } + + static long tryWriteLockUninterrupted(StampedLock sl, long time, TimeUnit unit) { + try { return sl.tryWriteLock(time, unit); } + catch (InterruptedException ex) { throw new AssertionError(ex); } + } + + /** + * Invalid write stamps result in IllegalMonitorStateException + */ + public void testInvalidWriteStampsThrowIllegalMonitorStateException() { + List> writeLockers = new ArrayList<>(); + writeLockers.add((sl) -> sl.writeLock()); + writeLockers.add((sl) -> writeLockInterruptiblyUninterrupted(sl)); + writeLockers.add((sl) -> tryWriteLockUninterrupted(sl, Long.MIN_VALUE, DAYS)); + writeLockers.add((sl) -> tryWriteLockUninterrupted(sl, 0, DAYS)); + + List> mutaters = new ArrayList<>(); + mutaters.add((sl) -> {}); + mutaters.add((sl) -> sl.readLock()); + for (Function writeLocker : writeLockers) + mutaters.add((sl) -> writeLocker.apply(sl)); + + List> writeUnlockers = new ArrayList<>(); + writeUnlockers.add((sl, stamp) -> sl.unlockWrite(stamp)); + writeUnlockers.add((sl, stamp) -> assertTrue(sl.tryUnlockWrite())); + writeUnlockers.add((sl, stamp) -> sl.asWriteLock().unlock()); + writeUnlockers.add((sl, stamp) -> sl.unlock(stamp)); + + for (Function writeLocker : writeLockers) + for (BiConsumer writeUnlocker : writeUnlockers) + for (Consumer mutater : mutaters) { + StampedLock sl = new StampedLock(); + long stamp = writeLocker.apply(sl); + assertTrue(stamp != 0L); + assertThrows(IllegalMonitorStateException.class, + () -> sl.unlockRead(stamp)); + writeUnlocker.accept(sl, stamp); + mutater.accept(sl); + assertThrows(IllegalMonitorStateException.class, + () -> sl.unlock(stamp), + () -> sl.unlockRead(stamp), + () -> sl.unlockWrite(stamp)); + } + } + }