mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19:54:13 +00:00
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:
parent
2b17ba7766
commit
1445835c4f
@ -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");
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user