fix Thread.join when using Android class library

Android's Thread.join expects the VM to null-out Thread.vmThread when
the thread exits.  Otherwise, it will block forever.
This commit is contained in:
Joel Dice 2014-02-25 12:33:12 -07:00
parent 2b17ba7766
commit 1445835c4f
2 changed files with 49 additions and 23 deletions

View File

@ -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<object>(thread, fieldOffset(t, field)) == 0) {
PROTECT(t, field);
if (fieldAtOffset<object>(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<object>(t->javaThread, offset);
if (vmt) {
PROTECT(t, vmt);
vm::acquire(t, vmt);
fieldAtOffset<object>(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");

View File

@ -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");
}