undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
405
test/jdk/java/util/concurrent/tck/LockSupportTest.java
Normal file
405
test/jdk/java/util/concurrent/tck/LockSupportTest.java
Normal file
|
|
@ -0,0 +1,405 @@
|
|||
/*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is available under and governed by the GNU General Public
|
||||
* License version 2 only, as published by the Free Software Foundation.
|
||||
* However, the following notice accompanied the original version of this
|
||||
* file:
|
||||
*
|
||||
* Written by Doug Lea and Martin Buchholz with assistance from
|
||||
* members of JCP JSR-166 Expert Group and released to the public
|
||||
* domain, as explained at
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
* Other contributors include Andrew Wright, Jeffrey Hayes,
|
||||
* Pat Fisher, Mike Judd.
|
||||
*/
|
||||
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
public class LockSupportTest extends JSR166TestCase {
|
||||
public static void main(String[] args) {
|
||||
main(suite(), args);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return new TestSuite(LockSupportTest.class);
|
||||
}
|
||||
|
||||
static {
|
||||
// Reduce the risk of rare disastrous classloading in first call to
|
||||
// LockSupport.park: https://bugs.openjdk.org/browse/JDK-8074773
|
||||
Class<?> ensureLoaded = LockSupport.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the blocker object used by tests in this file.
|
||||
* Any old object will do; we'll return a convenient one.
|
||||
*/
|
||||
static Object theBlocker() {
|
||||
return LockSupportTest.class;
|
||||
}
|
||||
|
||||
enum ParkMethod {
|
||||
park() {
|
||||
void park() {
|
||||
LockSupport.park();
|
||||
}
|
||||
Thread.State parkedState() { return Thread.State.WAITING; }
|
||||
},
|
||||
parkUntil() {
|
||||
void park(long millis) {
|
||||
LockSupport.parkUntil(deadline(millis));
|
||||
}
|
||||
},
|
||||
parkNanos() {
|
||||
void park(long millis) {
|
||||
LockSupport.parkNanos(MILLISECONDS.toNanos(millis));
|
||||
}
|
||||
},
|
||||
parkBlocker() {
|
||||
void park() {
|
||||
LockSupport.park(theBlocker());
|
||||
}
|
||||
Thread.State parkedState() { return Thread.State.WAITING; }
|
||||
},
|
||||
parkUntilBlocker() {
|
||||
void park(long millis) {
|
||||
LockSupport.parkUntil(theBlocker(), deadline(millis));
|
||||
}
|
||||
},
|
||||
parkNanosBlocker() {
|
||||
void park(long millis) {
|
||||
LockSupport.parkNanos(theBlocker(),
|
||||
MILLISECONDS.toNanos(millis));
|
||||
}
|
||||
};
|
||||
|
||||
void park() { park(2 * LONG_DELAY_MS); }
|
||||
void park(long millis) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
Thread.State parkedState() { return Thread.State.TIMED_WAITING; }
|
||||
|
||||
/** Returns a deadline to use with parkUntil. */
|
||||
long deadline(long millis) {
|
||||
// beware of rounding
|
||||
return System.currentTimeMillis() + millis + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* park is released by subsequent unpark
|
||||
*/
|
||||
public void testParkBeforeUnpark_park() {
|
||||
testParkBeforeUnpark(ParkMethod.park);
|
||||
}
|
||||
public void testParkBeforeUnpark_parkNanos() {
|
||||
testParkBeforeUnpark(ParkMethod.parkNanos);
|
||||
}
|
||||
public void testParkBeforeUnpark_parkUntil() {
|
||||
testParkBeforeUnpark(ParkMethod.parkUntil);
|
||||
}
|
||||
public void testParkBeforeUnpark_parkBlocker() {
|
||||
testParkBeforeUnpark(ParkMethod.parkBlocker);
|
||||
}
|
||||
public void testParkBeforeUnpark_parkNanosBlocker() {
|
||||
testParkBeforeUnpark(ParkMethod.parkNanosBlocker);
|
||||
}
|
||||
public void testParkBeforeUnpark_parkUntilBlocker() {
|
||||
testParkBeforeUnpark(ParkMethod.parkUntilBlocker);
|
||||
}
|
||||
public void testParkBeforeUnpark(final ParkMethod parkMethod) {
|
||||
final CountDownLatch pleaseUnpark = new CountDownLatch(1);
|
||||
Thread t = newStartedThread(new CheckedRunnable() {
|
||||
public void realRun() {
|
||||
pleaseUnpark.countDown();
|
||||
parkMethod.park();
|
||||
}});
|
||||
|
||||
await(pleaseUnpark);
|
||||
LockSupport.unpark(t);
|
||||
awaitTermination(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* park is released by preceding unpark
|
||||
*/
|
||||
public void testParkAfterUnpark_park() {
|
||||
testParkAfterUnpark(ParkMethod.park);
|
||||
}
|
||||
public void testParkAfterUnpark_parkNanos() {
|
||||
testParkAfterUnpark(ParkMethod.parkNanos);
|
||||
}
|
||||
public void testParkAfterUnpark_parkUntil() {
|
||||
testParkAfterUnpark(ParkMethod.parkUntil);
|
||||
}
|
||||
public void testParkAfterUnpark_parkBlocker() {
|
||||
testParkAfterUnpark(ParkMethod.parkBlocker);
|
||||
}
|
||||
public void testParkAfterUnpark_parkNanosBlocker() {
|
||||
testParkAfterUnpark(ParkMethod.parkNanosBlocker);
|
||||
}
|
||||
public void testParkAfterUnpark_parkUntilBlocker() {
|
||||
testParkAfterUnpark(ParkMethod.parkUntilBlocker);
|
||||
}
|
||||
public void testParkAfterUnpark(final ParkMethod parkMethod) {
|
||||
final CountDownLatch pleaseUnpark = new CountDownLatch(1);
|
||||
final AtomicBoolean pleasePark = new AtomicBoolean(false);
|
||||
Thread t = newStartedThread(new CheckedRunnable() {
|
||||
public void realRun() {
|
||||
pleaseUnpark.countDown();
|
||||
while (!pleasePark.get())
|
||||
Thread.yield();
|
||||
parkMethod.park();
|
||||
}});
|
||||
|
||||
await(pleaseUnpark);
|
||||
LockSupport.unpark(t);
|
||||
pleasePark.set(true);
|
||||
awaitTermination(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* park is released by subsequent interrupt
|
||||
*/
|
||||
public void testParkBeforeInterrupt_park() {
|
||||
testParkBeforeInterrupt(ParkMethod.park);
|
||||
}
|
||||
public void testParkBeforeInterrupt_parkNanos() {
|
||||
testParkBeforeInterrupt(ParkMethod.parkNanos);
|
||||
}
|
||||
public void testParkBeforeInterrupt_parkUntil() {
|
||||
testParkBeforeInterrupt(ParkMethod.parkUntil);
|
||||
}
|
||||
public void testParkBeforeInterrupt_parkBlocker() {
|
||||
testParkBeforeInterrupt(ParkMethod.parkBlocker);
|
||||
}
|
||||
public void testParkBeforeInterrupt_parkNanosBlocker() {
|
||||
testParkBeforeInterrupt(ParkMethod.parkNanosBlocker);
|
||||
}
|
||||
public void testParkBeforeInterrupt_parkUntilBlocker() {
|
||||
testParkBeforeInterrupt(ParkMethod.parkUntilBlocker);
|
||||
}
|
||||
public void testParkBeforeInterrupt(final ParkMethod parkMethod) {
|
||||
final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
|
||||
Thread t = newStartedThread(new CheckedRunnable() {
|
||||
public void realRun() {
|
||||
pleaseInterrupt.countDown();
|
||||
for (int tries = MAX_SPURIOUS_WAKEUPS; tries-->0; ) {
|
||||
parkMethod.park();
|
||||
if (Thread.interrupted())
|
||||
return;
|
||||
}
|
||||
fail("too many consecutive spurious wakeups?");
|
||||
}});
|
||||
|
||||
await(pleaseInterrupt);
|
||||
assertThreadBlocks(t, parkMethod.parkedState());
|
||||
t.interrupt();
|
||||
awaitTermination(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* park is released by preceding interrupt
|
||||
*/
|
||||
public void testParkAfterInterrupt_park() {
|
||||
testParkAfterInterrupt(ParkMethod.park);
|
||||
}
|
||||
public void testParkAfterInterrupt_parkNanos() {
|
||||
testParkAfterInterrupt(ParkMethod.parkNanos);
|
||||
}
|
||||
public void testParkAfterInterrupt_parkUntil() {
|
||||
testParkAfterInterrupt(ParkMethod.parkUntil);
|
||||
}
|
||||
public void testParkAfterInterrupt_parkBlocker() {
|
||||
testParkAfterInterrupt(ParkMethod.parkBlocker);
|
||||
}
|
||||
public void testParkAfterInterrupt_parkNanosBlocker() {
|
||||
testParkAfterInterrupt(ParkMethod.parkNanosBlocker);
|
||||
}
|
||||
public void testParkAfterInterrupt_parkUntilBlocker() {
|
||||
testParkAfterInterrupt(ParkMethod.parkUntilBlocker);
|
||||
}
|
||||
public void testParkAfterInterrupt(final ParkMethod parkMethod) {
|
||||
final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
|
||||
Thread t = newStartedThread(new CheckedRunnable() {
|
||||
public void realRun() throws Exception {
|
||||
pleaseInterrupt.countDown();
|
||||
while (!Thread.currentThread().isInterrupted())
|
||||
Thread.yield();
|
||||
parkMethod.park();
|
||||
assertTrue(Thread.interrupted());
|
||||
}});
|
||||
|
||||
await(pleaseInterrupt);
|
||||
t.interrupt();
|
||||
awaitTermination(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* timed park times out if not unparked
|
||||
*/
|
||||
public void testParkTimesOut_parkNanos() {
|
||||
testParkTimesOut(ParkMethod.parkNanos);
|
||||
}
|
||||
public void testParkTimesOut_parkUntil() {
|
||||
testParkTimesOut(ParkMethod.parkUntil);
|
||||
}
|
||||
public void testParkTimesOut_parkNanosBlocker() {
|
||||
testParkTimesOut(ParkMethod.parkNanosBlocker);
|
||||
}
|
||||
public void testParkTimesOut_parkUntilBlocker() {
|
||||
testParkTimesOut(ParkMethod.parkUntilBlocker);
|
||||
}
|
||||
public void testParkTimesOut(final ParkMethod parkMethod) {
|
||||
Thread t = newStartedThread(new CheckedRunnable() {
|
||||
public void realRun() {
|
||||
for (int tries = MAX_SPURIOUS_WAKEUPS; tries-->0; ) {
|
||||
long startTime = System.nanoTime();
|
||||
parkMethod.park(timeoutMillis());
|
||||
if (millisElapsedSince(startTime) >= timeoutMillis())
|
||||
return;
|
||||
}
|
||||
fail("too many consecutive spurious wakeups?");
|
||||
}});
|
||||
|
||||
awaitTermination(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* getBlocker(null) throws NullPointerException
|
||||
*/
|
||||
public void testGetBlockerNull() {
|
||||
try {
|
||||
LockSupport.getBlocker(null);
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* getBlocker returns the blocker object passed to park
|
||||
*/
|
||||
public void testGetBlocker_parkBlocker() {
|
||||
testGetBlocker(ParkMethod.parkBlocker);
|
||||
}
|
||||
public void testGetBlocker_parkNanosBlocker() {
|
||||
testGetBlocker(ParkMethod.parkNanosBlocker);
|
||||
}
|
||||
public void testGetBlocker_parkUntilBlocker() {
|
||||
testGetBlocker(ParkMethod.parkUntilBlocker);
|
||||
}
|
||||
public void testGetBlocker(final ParkMethod parkMethod) {
|
||||
final CountDownLatch started = new CountDownLatch(1);
|
||||
Thread t = newStartedThread(new CheckedRunnable() {
|
||||
public void realRun() {
|
||||
Thread t = Thread.currentThread();
|
||||
started.countDown();
|
||||
for (int tries = MAX_SPURIOUS_WAKEUPS; tries-->0; ) {
|
||||
assertNull(LockSupport.getBlocker(t));
|
||||
parkMethod.park();
|
||||
assertNull(LockSupport.getBlocker(t));
|
||||
if (Thread.interrupted())
|
||||
return;
|
||||
}
|
||||
fail("too many consecutive spurious wakeups?");
|
||||
}});
|
||||
|
||||
long startTime = System.nanoTime();
|
||||
await(started);
|
||||
for (;;) {
|
||||
Object x = LockSupport.getBlocker(t);
|
||||
if (x == theBlocker()) { // success
|
||||
t.interrupt();
|
||||
awaitTermination(t);
|
||||
assertNull(LockSupport.getBlocker(t));
|
||||
return;
|
||||
} else {
|
||||
assertNull(x); // ok
|
||||
if (millisElapsedSince(startTime) > LONG_DELAY_MS)
|
||||
fail("timed out");
|
||||
if (t.getState() == Thread.State.TERMINATED)
|
||||
break;
|
||||
Thread.yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* timed park(0) returns immediately.
|
||||
*
|
||||
* Requires hotspot fix for:
|
||||
* 6763959 java.util.concurrent.locks.LockSupport.parkUntil(0) blocks forever
|
||||
* which is in jdk7-b118 and 6u25.
|
||||
*/
|
||||
public void testPark0_parkNanos() {
|
||||
testPark0(ParkMethod.parkNanos);
|
||||
}
|
||||
public void testPark0_parkUntil() {
|
||||
testPark0(ParkMethod.parkUntil);
|
||||
}
|
||||
public void testPark0_parkNanosBlocker() {
|
||||
testPark0(ParkMethod.parkNanosBlocker);
|
||||
}
|
||||
public void testPark0_parkUntilBlocker() {
|
||||
testPark0(ParkMethod.parkUntilBlocker);
|
||||
}
|
||||
public void testPark0(final ParkMethod parkMethod) {
|
||||
Thread t = newStartedThread(new CheckedRunnable() {
|
||||
public void realRun() {
|
||||
parkMethod.park(0L);
|
||||
}});
|
||||
|
||||
awaitTermination(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* timed park(Long.MIN_VALUE) returns immediately.
|
||||
*/
|
||||
public void testParkNeg_parkNanos() {
|
||||
testParkNeg(ParkMethod.parkNanos);
|
||||
}
|
||||
public void testParkNeg_parkUntil() {
|
||||
testParkNeg(ParkMethod.parkUntil);
|
||||
}
|
||||
public void testParkNeg_parkNanosBlocker() {
|
||||
testParkNeg(ParkMethod.parkNanosBlocker);
|
||||
}
|
||||
public void testParkNeg_parkUntilBlocker() {
|
||||
testParkNeg(ParkMethod.parkUntilBlocker);
|
||||
}
|
||||
public void testParkNeg(final ParkMethod parkMethod) {
|
||||
Thread t = newStartedThread(new CheckedRunnable() {
|
||||
public void realRun() {
|
||||
parkMethod.park(Long.MIN_VALUE);
|
||||
}});
|
||||
|
||||
awaitTermination(t);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue