diff --git a/src/classpath-android.cpp b/src/classpath-android.cpp index 21e4cb6a6b..3cbbc33292 100644 --- a/src/classpath-android.cpp +++ b/src/classpath-android.cpp @@ -157,17 +157,11 @@ makeField(Thread* t, object c, unsigned index) return makeJfield(t, 0, c, type, 0, 0, name, index); } -void -initVmThread(Thread* t, object thread) +void initVmThread(Thread* t, object thread, unsigned offset) { PROTECT(t, thread); - object field = resolveField - (t, objectClass(t, thread), "vmThread", "Ljava/lang/VMThread;"); - - if (fieldAtOffset(thread, fieldOffset(t, field)) == 0) { - PROTECT(t, field); - + if (fieldAtOffset(thread, offset) == 0) { object c = resolveClass (t, root(t, Machine::BootLoader), "java/lang/VMThread"); PROTECT(t, c); @@ -180,7 +174,7 @@ initVmThread(Thread* t, object thread) t->m->processor->invoke(t, constructor, instance, thread); - set(t, thread, fieldOffset(t, field), instance); + set(t, thread, offset, instance); } if (threadGroup(t, thread) == 0) { @@ -189,6 +183,17 @@ initVmThread(Thread* t, object thread) } } +void initVmThread(Thread* t, object thread) +{ + initVmThread( + t, + thread, + fieldOffset( + t, + resolveField( + t, objectClass(t, thread), "vmThread", "Ljava/lang/VMThread;"))); +} + object translateStackTrace(Thread* t, object raw) { @@ -353,14 +358,28 @@ class MyClasspath : public Classpath { // later when we try to acquire it: objectMonitor(t, t->javaThread, true); - THREAD_RESOURCE0(t, { - vm::acquire(t, t->javaThread); - t->flags &= ~Thread::ActiveFlag; - vm::notifyAll(t, t->javaThread); - vm::release(t, t->javaThread); + object field = resolveField( + t, objectClass(t, t->javaThread), "vmThread", "Ljava/lang/VMThread;"); + + unsigned offset = fieldOffset(t, field); + + THREAD_RESOURCE(t, unsigned, offset, { + object vmt = fieldAtOffset(t->javaThread, offset); + if (vmt) { + PROTECT(t, vmt); + vm::acquire(t, vmt); + fieldAtOffset(t->javaThread, offset) = 0; + vm::notifyAll(t, vmt); + vm::release(t, vmt); + } + + vm::acquire(t, t->javaThread); + t->flags &= ~Thread::ActiveFlag; + vm::notifyAll(t, t->javaThread); + vm::release(t, t->javaThread); }); - initVmThread(t, t->javaThread); + initVmThread(t, t->javaThread, offset); object method = resolveMethod (t, root(t, Machine::BootLoader), "java/lang/Thread", "run", "()V"); diff --git a/test/Threads.java b/test/Threads.java index a6292e74fb..0cef7c75b7 100644 --- a/test/Threads.java +++ b/test/Threads.java @@ -1,15 +1,11 @@ public class Threads implements Runnable { - public static void main(String[] args) { + public static void main(String[] args) throws Exception { { Threads test = new Threads(); Thread thread = new Thread(test); - try { - synchronized (test) { - thread.start(); - test.wait(); - } - } catch (Throwable e) { - e.printStackTrace(); + synchronized (test) { + thread.start(); + test.wait(); } } @@ -33,6 +29,17 @@ public class Threads implements Runnable { System.out.println("\nInterrupted!"); } + { Thread thread = new Thread() { + @Override + public void run() { + // do nothing + } + }; + + thread.start(); + thread.join(); + } + System.out.println("finished"); }