Fix Thread.sleep(0) of an interrupted thread
Bug: 12929305
Change-Id: I3061c3345c68de8bcf438e6935446b4f7cd76001
diff --git a/libart/src/main/java/java/lang/Thread.java b/libart/src/main/java/java/lang/Thread.java
index 2cc2857..b826e66 100644
--- a/libart/src/main/java/java/lang/Thread.java
+++ b/libart/src/main/java/java/lang/Thread.java
@@ -993,9 +993,23 @@
* @see Thread#interrupt()
*/
public static void sleep(long millis, int nanos) throws InterruptedException {
+ if (millis < 0) {
+ throw new IllegalArgumentException("millis < 0: " + millis);
+ }
+ if (nanos < 0) {
+ throw new IllegalArgumentException("nanos < 0: " + nanos);
+ }
+ if (nanos > 999999) {
+ throw new IllegalArgumentException("nanos > 999999: " + nanos);
+ }
+
// The JLS 3rd edition, section 17.9 says: "...sleep for zero
// time...need not have observable effects."
if (millis == 0 && nanos == 0) {
+ // ...but we still have to handle being interrupted.
+ if (Thread.interrupted()) {
+ throw new InterruptedException();
+ }
return;
}
diff --git a/luni/src/test/java/libcore/java/lang/ThreadTest.java b/luni/src/test/java/libcore/java/lang/ThreadTest.java
index 68ad795..8545a20 100644
--- a/luni/src/test/java/libcore/java/lang/ThreadTest.java
+++ b/luni/src/test/java/libcore/java/lang/ThreadTest.java
@@ -59,15 +59,46 @@
}
public void testThreadSleep() throws Exception {
- int millis = 1000;
- long start = System.currentTimeMillis();
+ int millis = 1000;
+ long start = System.currentTimeMillis();
- Thread.sleep(millis);
+ Thread.sleep(millis);
- long elapsed = System.currentTimeMillis() - start;
- long offBy = Math.abs(elapsed - millis);
+ long elapsed = System.currentTimeMillis() - start;
+ long offBy = Math.abs(elapsed - millis);
- assertTrue("Actual sleep off by " + offBy + " ms", offBy <= 250);
+ assertTrue("Actual sleep off by " + offBy + " ms", offBy <= 250);
+ }
+
+ public void testThreadInterrupted() throws Exception {
+ Thread.currentThread().interrupt();
+ try {
+ Thread.sleep(0);
+ fail();
+ } catch (InterruptedException e) {
+ assertFalse(Thread.currentThread().isInterrupted());
+ }
+ }
+
+ public void testThreadSleepIllegalArguments() throws Exception {
+
+ try {
+ Thread.sleep(-1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ Thread.sleep(0, -1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ Thread.sleep(0, 1000000);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
}
public void testThreadWakeup() throws Exception {