Fix error in Object.wait. Make junit working with new async approach

This commit is contained in:
Alexey Andreev 2015-03-12 11:44:17 +04:00
parent 2ef8f9c0e8
commit aad95014fe
4 changed files with 73 additions and 23 deletions

View File

@ -97,6 +97,12 @@ public class TObject {
o.monitor.count += count; o.monitor.count += count;
callback.complete(null); callback.complete(null);
return; return;
} else if (o.monitor.owner == null) {
o.monitor.owner = thread;
TThread.setCurrentThread(thread);
o.monitor.count += count;
callback.complete(null);
return;
} }
o.monitor.enteringThreads.add(new PlatformRunnable() { o.monitor.enteringThreads.add(new PlatformRunnable() {
@Override public void run() { @Override public void run() {

View File

@ -442,6 +442,7 @@ function TeaVMThread(runner) {
this.suspendCallback = null; this.suspendCallback = null;
this.runner = runner; this.runner = runner;
this.attribute = null; this.attribute = null;
this.completeCallback = null;
} }
TeaVMThread.prototype.push = function(value) { TeaVMThread.prototype.push = function(value) {
this.stack.push(value); this.stack.push(value);
@ -460,7 +461,7 @@ TeaVMThread.prototype.suspend = function(callback) {
this.suspendCallback = callback; this.suspendCallback = callback;
this.status = 1; this.status = 1;
} }
TeaVMThread.prototype.start = function() { TeaVMThread.prototype.start = function(callback) {
if (this.status != 3) { if (this.status != 3) {
throw new Error("Thread already started"); throw new Error("Thread already started");
} }
@ -468,6 +469,7 @@ TeaVMThread.prototype.start = function() {
throw new Error("Another thread is running"); throw new Error("Another thread is running");
} }
this.status = 0; this.status = 0;
this.completeCallback = callback ? callback : function() {};
this.run(); this.run();
} }
TeaVMThread.prototype.resume = function() { TeaVMThread.prototype.resume = function() {
@ -479,8 +481,11 @@ TeaVMThread.prototype.resume = function() {
} }
TeaVMThread.prototype.run = function() { TeaVMThread.prototype.run = function() {
$rt_currentNativeThread = this; $rt_currentNativeThread = this;
var result;
try { try {
this.runner(); result = this.runner();
} catch (e) {
result = e;
} finally { } finally {
$rt_currentNativeThread = null; $rt_currentNativeThread = null;
} }
@ -491,6 +496,8 @@ TeaVMThread.prototype.run = function() {
callback(function() { callback(function() {
self.resume(); self.resume();
}); });
} else if (this.status === 0) {
this.completeCallback(result);
} }
} }
function $rt_suspending() { function $rt_suspending() {
@ -504,8 +511,8 @@ function $rt_resuming() {
function $rt_suspend(callback) { function $rt_suspend(callback) {
return $rt_nativeThread().suspend(callback); return $rt_nativeThread().suspend(callback);
} }
function $rt_startThread(runner) { function $rt_startThread(runner, callback) {
new TeaVMThread(runner).start(); new TeaVMThread(runner).start(callback);
} }
var $rt_currentNativeThread = null; var $rt_currentNativeThread = null;
function $rt_nativeThread() { function $rt_nativeThread() {

View File

@ -368,26 +368,52 @@ TreeNode.prototype.select = function() {
var JUnitClient = {}; var JUnitClient = {};
JUnitClient.run = function() { JUnitClient.run = function() {
var handler = window.addEventListener("message", function() { var handler = window.addEventListener("message", $rt_threadStarter(function() {
window.removeEventListener("message", handler); var thread = $rt_nativeThread();
var message = {}; var instance;
var ptr = 0;
var message;
if (thread.isResuming()) {
ptr = thread.pop();
instance = thread.pop();
}
loop: while (true) { switch (ptr) {
case 0:
instance = new TestClass();
ptr = 1;
case 1:
try { try {
var instance = new TestClass();
initInstance(instance); initInstance(instance);
runTest(instance, function(restore) { } catch (e) {
message = {};
JUnitClient.makeErrorMessage(message, e);
break loop;
}
if (thread.isSuspending()) {
thread.push(instance);
thread.push(ptr);
return;
}
ptr = 2;
case 2:
try { try {
var result = restore(); runTest(instance);
} catch (e) {
message = {};
JUnitClient.makeErrorMessage(message, e);
break loop;
}
if (thread.isSuspending()) {
thread.push(instance);
thread.push(ptr);
return;
}
message = {};
message.status = "ok"; message.status = "ok";
} catch (e) { break loop;
JUnitClient.makeErrorMessage(message, e); }}
}
window.parent.postMessage(JSON.stringify(message), "*"); window.parent.postMessage(JSON.stringify(message), "*");
}); }));
} catch (e) {
JUnitClient.makeErrorMessage(message, e);
window.parent.postMessage(JSON.stringify(message), "*");
}
});
} }
JUnitClient.makeErrorMessage = function(message, e) { JUnitClient.makeErrorMessage = function(message, e) {
message.status = "exception"; message.status = "exception";

View File

@ -67,4 +67,15 @@ public class ObjectTest {
assertTrue(new Object[2].toString().startsWith("[Ljava.lang.Object;@")); assertTrue(new Object[2].toString().startsWith("[Ljava.lang.Object;@"));
assertTrue(new byte[3].toString().startsWith("[B@")); assertTrue(new byte[3].toString().startsWith("[B@"));
} }
@Test
public void waitWorks() throws InterruptedException {
long start = System.currentTimeMillis();
final Object lock = new Object();
synchronized (lock) {
lock.wait(100);
}
long end = System.currentTimeMillis();
assertTrue(end - start > 100);
}
} }