mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +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);
|
return makeJfield(t, 0, c, type, 0, 0, name, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void initVmThread(Thread* t, object thread, unsigned offset)
|
||||||
initVmThread(Thread* t, object thread)
|
|
||||||
{
|
{
|
||||||
PROTECT(t, thread);
|
PROTECT(t, thread);
|
||||||
|
|
||||||
object field = resolveField
|
if (fieldAtOffset<object>(thread, offset) == 0) {
|
||||||
(t, objectClass(t, thread), "vmThread", "Ljava/lang/VMThread;");
|
|
||||||
|
|
||||||
if (fieldAtOffset<object>(thread, fieldOffset(t, field)) == 0) {
|
|
||||||
PROTECT(t, field);
|
|
||||||
|
|
||||||
object c = resolveClass
|
object c = resolveClass
|
||||||
(t, root(t, Machine::BootLoader), "java/lang/VMThread");
|
(t, root(t, Machine::BootLoader), "java/lang/VMThread");
|
||||||
PROTECT(t, c);
|
PROTECT(t, c);
|
||||||
@ -180,7 +174,7 @@ initVmThread(Thread* t, object thread)
|
|||||||
|
|
||||||
t->m->processor->invoke(t, constructor, instance, 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) {
|
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
|
object
|
||||||
translateStackTrace(Thread* t, object raw)
|
translateStackTrace(Thread* t, object raw)
|
||||||
{
|
{
|
||||||
@ -353,14 +358,28 @@ class MyClasspath : public Classpath {
|
|||||||
// later when we try to acquire it:
|
// later when we try to acquire it:
|
||||||
objectMonitor(t, t->javaThread, true);
|
objectMonitor(t, t->javaThread, true);
|
||||||
|
|
||||||
THREAD_RESOURCE0(t, {
|
object field = resolveField(
|
||||||
vm::acquire(t, t->javaThread);
|
t, objectClass(t, t->javaThread), "vmThread", "Ljava/lang/VMThread;");
|
||||||
t->flags &= ~Thread::ActiveFlag;
|
|
||||||
vm::notifyAll(t, t->javaThread);
|
unsigned offset = fieldOffset(t, field);
|
||||||
vm::release(t, t->javaThread);
|
|
||||||
|
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
|
object method = resolveMethod
|
||||||
(t, root(t, Machine::BootLoader), "java/lang/Thread", "run", "()V");
|
(t, root(t, Machine::BootLoader), "java/lang/Thread", "run", "()V");
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
public class Threads implements Runnable {
|
public class Threads implements Runnable {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) throws Exception {
|
||||||
{ Threads test = new Threads();
|
{ Threads test = new Threads();
|
||||||
Thread thread = new Thread(test);
|
Thread thread = new Thread(test);
|
||||||
|
|
||||||
try {
|
synchronized (test) {
|
||||||
synchronized (test) {
|
thread.start();
|
||||||
thread.start();
|
test.wait();
|
||||||
test.wait();
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,6 +29,17 @@ public class Threads implements Runnable {
|
|||||||
System.out.println("\nInterrupted!");
|
System.out.println("\nInterrupted!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ Thread thread = new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
thread.start();
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
|
||||||
System.out.println("finished");
|
System.out.println("finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user