diff options
author | jfrijters <jfrijters> | 2010-08-09 16:27:39 +0400 |
---|---|---|
committer | jfrijters <jfrijters> | 2010-08-09 16:27:39 +0400 |
commit | 4140a2c52b0ea1d9326d42fc664d75a64f3f36d1 (patch) | |
tree | 873ea6a3bb071bbfadb18c8b8ff5442082625858 | |
parent | 1f08d17cd3523c8f4db032ee8fbe93a5794cf85c (diff) |
- Split objectWait into two. One for the nanos variant and one that does the actual waiting.
- Fixed edge case where timeout == Long.MAX_VALUE and nanos >= 500000 that should cause IllegalArgumentException (to be compatible with the JDK, although that is arguably a JDK bug).
- Fixed exception when timeout > Integer.MAX_VALUE. Thanks to Andy Malakov for reporting this.
-rw-r--r-- | openjdk/java/lang/Thread.java | 19 | ||||
-rw-r--r-- | openjdk/map.xml | 6 |
2 files changed, 19 insertions, 6 deletions
diff --git a/openjdk/java/lang/Thread.java b/openjdk/java/lang/Thread.java index aea88f93..eb635c58 100644 --- a/openjdk/java/lang/Thread.java +++ b/openjdk/java/lang/Thread.java @@ -2311,7 +2311,7 @@ class Thread implements Runnable { } } - // [IKVM] this the implementation of Object.wait(). It is hooked up in map.xml. + // [IKVM] this the implementation of Object.wait(long timeout, int nanos). It is hooked up in map.xml. static void objectWait(Object o, long timeout, int nanos) throws InterruptedException { if (o == null) { throw new NullPointerException(); @@ -2325,6 +2325,17 @@ class Thread implements Runnable { if (nanos >= 500000 || (nanos != 0 && timeout == 0)) { timeout++; } + objectWait(o, timeout); + } + + // [IKVM] this the implementation of Object.wait(long timeout). It is hooked up in map.xml. + static void objectWait(Object o, long timeout) throws InterruptedException { + if (o == null) { + throw new NullPointerException(); + } + if (timeout < 0) { + throw new IllegalArgumentException("timeout value is negative"); + } Thread t = currentThread(); t.enterInterruptableWait(timeout != 0); try { @@ -2333,7 +2344,11 @@ class Thread implements Runnable { cli.System.Threading.Monitor.Wait(o); } else { - cli.System.Threading.Monitor.Wait(o, new cli.System.TimeSpan(timeout * 10000)); + // We wait a maximum of Integer.MAX_VALUE milliseconds, because that is the maximum that Monitor.Wait will wait. + // Note that the Object.wait() specification allows for spurious wakeups, so this isn't a problem. Trying to + // emulate a longer wait with multiple Monitor.Wait() calls is not allowed, because that would mean that + // we acquire and release the synchronization lock multiple times during the wait. + cli.System.Threading.Monitor.Wait(o, (int)Math.min(timeout, Integer.MAX_VALUE)); } } catch (cli.System.Threading.ThreadInterruptedException _) { diff --git a/openjdk/map.xml b/openjdk/map.xml index 2eb085c6..95d6680e 100644 --- a/openjdk/map.xml +++ b/openjdk/map.xml @@ -47,8 +47,7 @@ <ldarg_0 /> <ldc_i4_0 /> <conv_i8 /> - <ldc_i4_0 /> - <call class="java.lang.Thread" name="objectWait" sig="(Ljava.lang.Object;JI)V" /> + <call class="java.lang.Thread" name="objectWait" sig="(Ljava.lang.Object;J)V" /> <ret /> </body> </method> @@ -58,8 +57,7 @@ <body> <ldarg_0 /> <ldarg_1 /> - <ldc_i4_0 /> - <call class="java.lang.Thread" name="objectWait" sig="(Ljava.lang.Object;JI)V" /> + <call class="java.lang.Thread" name="objectWait" sig="(Ljava.lang.Object;J)V" /> <ret /> </body> </method> |