Merge "Add missing SO_FLOW_SLA changes"
diff --git a/luni/src/test/java/libcore/java/lang/ThreadTest.java b/luni/src/test/java/libcore/java/lang/ThreadTest.java
index 10ca9a7..be16938 100644
--- a/luni/src/test/java/libcore/java/lang/ThreadTest.java
+++ b/luni/src/test/java/libcore/java/lang/ThreadTest.java
@@ -17,6 +17,8 @@
package libcore.java.lang;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicBoolean;
+
import junit.framework.Assert;
import junit.framework.TestCase;
import libcore.java.lang.ref.FinalizationTester;
@@ -179,6 +181,39 @@
}
}
+ // http://b/29746125
+ public void testParkUntilWithUnderflowValue() throws Exception {
+ final Thread current = Thread.currentThread();
+
+ // watchdog to unpark the tread in case it will be parked
+ AtomicBoolean afterPark = new AtomicBoolean(false);
+ AtomicBoolean wasParkedForLongTime = new AtomicBoolean(false);
+ Thread watchdog = new Thread() {
+ @Override public void run() {
+ try {
+ sleep(5000);
+ } catch(InterruptedException expected) {}
+
+ if (!afterPark.get()) {
+ wasParkedForLongTime.set(true);
+ current.unpark$();
+ }
+ }
+ };
+ watchdog.start();
+
+ // b/29746125 is caused by underflow: parkUntilArg - System.currentTimeMillis() > 0.
+ // parkUntil$ should return immediately for everyargument that's <=
+ // System.currentTimeMillis().
+ current.parkUntil$(Long.MIN_VALUE);
+ if (wasParkedForLongTime.get()) {
+ fail("Current thread was parked, but was expected to return immediately");
+ }
+ afterPark.set(true);
+ watchdog.interrupt();
+ watchdog.join();
+ }
+
// This method returns {@code null} if all tests pass, or a non-null String containing
// failure details if an error occured.
private static native String nativeTestNativeThreadNames();
diff --git a/ojluni/src/main/java/java/lang/Thread.java b/ojluni/src/main/java/java/lang/Thread.java
index cff47dc..f0e9a78 100644
--- a/ojluni/src/main/java/java/lang/Thread.java
+++ b/ojluni/src/main/java/java/lang/Thread.java
@@ -2183,11 +2183,18 @@
* spuriously return for any reason, and this situation
* can safely be construed as just such a spurious return.
*/
- long delayMillis = time - System.currentTimeMillis();
-
- if (delayMillis <= 0) {
+ final long currentTime = System.currentTimeMillis();
+ if (time <= currentTime) {
parkState = ParkState.UNPARKED;
} else {
+ long delayMillis = time - currentTime;
+ // Long.MAX_VALUE / NANOS_PER_MILLI (0x8637BD05SF6) is the largest
+ // long value that won't overflow to negative value when
+ // multiplyed by NANOS_PER_MILLI (10^6).
+ long maxValue = (Long.MAX_VALUE / NANOS_PER_MILLI);
+ if (delayMillis > maxValue) {
+ delayMillis = maxValue;
+ }
parkFor$(delayMillis * NANOS_PER_MILLI);
}
}