Jelajahi Sumber

[java] Fix Lock's Object.wait() implementation with regards to the exceptions that may be thrown and how to deal with them

Cauê Waneck 10 tahun lalu
induk
melakukan
9482f6a14e
2 mengubah file dengan 34 tambahan dan 11 penghapusan
  1. 12 11
      std/java/vm/Lock.hx
  2. 22 0
      tests/unit/src/unit/TestJava.hx

+ 12 - 11
std/java/vm/Lock.hx

@@ -10,7 +10,6 @@ import java.Lib;
 	**/
 	public function new()
 	{
-
 	}
 
 	/**
@@ -26,26 +25,28 @@ import java.Lib;
 				return true;
 			if (timeout == null)
 			{
-				try
+				while( releasedCount < 0 )
 				{
-					untyped __java__("this.wait()");
-				}
-				catch(e:Dynamic) {
-					throw e;
+					try
+					{
+						untyped __java__("this.wait()");
+					}
+					catch(e:java.lang.InterruptedException)
+					{
+					}
 				}
 			} else {
-				var t:Dynamic = this;
 				try
 				{
 					var t:haxe.Int64 = cast timeout * 1000;
-					untyped __java__("this.wait(t)");
+					untyped __java__("this.wait({0})",t);
 				}
-				catch(e:Dynamic) {
-					throw e;
+				catch(e:java.lang.InterruptedException)
+				{
 				}
 			}
 			ret = this.releasedCount >= 0;
-			if (!ret && ++this.releasedCount == 0) //even if timeout failed, we should release the lock; Other locks may be released then
+			if (++this.releasedCount == 0) //even if timeout failed, we should release the lock; Other locks may have been released in the meantime
 			{
 				untyped this.notify();
 			}

+ 22 - 0
tests/unit/src/unit/TestJava.hx

@@ -6,6 +6,7 @@ import haxe.test.Base.Base___InnerClass3__;
 import haxe.test.Base.Base___InnerClass3___InnerClass4__;
 import haxe.test.TEnum;
 import java.util.EnumSet;
+import java.vm.*;
 
 #if java
 class TestJava extends Test
@@ -30,6 +31,27 @@ class TestJava extends Test
 		t(haxe.uppercasepackage.Lowercase.lowercaseFound);
 	}
 
+	function testBasicLock()
+	{
+		var lock = new Lock();
+		//it starts locked
+		f(lock.wait(0.001));
+		lock.release();
+		t(lock.wait(.001));
+		f(lock.wait(.001));
+		f(lock.wait(.001));
+
+		lock.release();
+		t(lock.wait());
+		lock.release();
+		lock.release();
+		lock.release();
+		t(lock.wait());
+		t(lock.wait(.001));
+		t(lock.wait());
+		f(lock.wait(.001));
+	}
+
 	function testEnumSet()
 	{
 		var es1:EnumSet<TEnum> = EnumSet.noneOf(java.Lib.toNativeEnum(TEnum));