mirror of
https://github.com/corda/corda.git
synced 2025-02-02 17:21:06 +00:00
fix Thread.interrupt and Thread.interrupted
These were both totally broken; the latter wasn't even implemented. This commit fixes/implements them and adds a simple test to exercise them.
This commit is contained in:
parent
381165f26d
commit
b5192ae7a3
@ -139,9 +139,17 @@ public class Thread implements Runnable {
|
|||||||
|
|
||||||
public static native Thread currentThread();
|
public static native Thread currentThread();
|
||||||
|
|
||||||
public native void interrupt();
|
public void interrupt() {
|
||||||
|
interrupt(peer);
|
||||||
|
}
|
||||||
|
|
||||||
public native boolean interrupted();
|
private static native boolean interrupt(long peer);
|
||||||
|
|
||||||
|
public boolean interrupted() {
|
||||||
|
return interrupted(peer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native boolean interrupted(long peer);
|
||||||
|
|
||||||
public static boolean isInterrupted() {
|
public static boolean isInterrupted() {
|
||||||
return currentThread().interrupted;
|
return currentThread().interrupted;
|
||||||
|
@ -554,6 +554,15 @@ Avian_java_lang_Thread_interrupt
|
|||||||
interrupt(t, reinterpret_cast<Thread*>(peer));
|
interrupt(t, reinterpret_cast<Thread*>(peer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
|
Avian_java_lang_Thread_interrupted
|
||||||
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
int64_t peer; memcpy(&peer, arguments, 8);
|
||||||
|
|
||||||
|
return getAndClearInterrupted(t, reinterpret_cast<Thread*>(peer));
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT int64_t JNICALL
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
Avian_java_lang_Thread_getStackTrace
|
Avian_java_lang_Thread_getStackTrace
|
||||||
(Thread* t, object, uintptr_t* arguments)
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
|
@ -3236,6 +3236,18 @@ interrupt(Thread* t, Thread* target)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
getAndClearInterrupted(Thread* t, Thread* target)
|
||||||
|
{
|
||||||
|
if (acquireSystem(t, target)) {
|
||||||
|
bool result = target->systemThread->getAndClearInterrupted();
|
||||||
|
releaseSystem(t, target);
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
intern(Thread* t, object s);
|
intern(Thread* t, object s);
|
||||||
|
|
||||||
|
@ -151,6 +151,16 @@ class MySystem: public System {
|
|||||||
expect(s, rv == 0);
|
expect(s, rv == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool getAndClearInterrupted() {
|
||||||
|
ACQUIRE(mutex);
|
||||||
|
|
||||||
|
bool interrupted = r->interrupted();
|
||||||
|
|
||||||
|
r->setInterrupted(false);
|
||||||
|
|
||||||
|
return interrupted;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void join() {
|
virtual void join() {
|
||||||
int rv UNUSED = pthread_join(thread, 0);
|
int rv UNUSED = pthread_join(thread, 0);
|
||||||
expect(s, rv == 0);
|
expect(s, rv == 0);
|
||||||
|
@ -29,6 +29,7 @@ class System {
|
|||||||
class Thread {
|
class Thread {
|
||||||
public:
|
public:
|
||||||
virtual void interrupt() = 0;
|
virtual void interrupt() = 0;
|
||||||
|
virtual bool getAndClearInterrupted() = 0;
|
||||||
virtual void join() = 0;
|
virtual void join() = 0;
|
||||||
virtual void dispose() = 0;
|
virtual void dispose() = 0;
|
||||||
};
|
};
|
||||||
|
@ -100,6 +100,16 @@ class MySystem: public System {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool getAndClearInterrupted() {
|
||||||
|
ACQUIRE(s, mutex);
|
||||||
|
|
||||||
|
bool interrupted = r->interrupted();
|
||||||
|
|
||||||
|
r->setInterrupted(false);
|
||||||
|
|
||||||
|
return interrupted;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void join() {
|
virtual void join() {
|
||||||
int r UNUSED = WaitForSingleObject(thread, INFINITE);
|
int r UNUSED = WaitForSingleObject(thread, INFINITE);
|
||||||
assert(s, r == WAIT_OBJECT_0);
|
assert(s, r == WAIT_OBJECT_0);
|
||||||
|
@ -1,15 +1,36 @@
|
|||||||
public class Threads implements Runnable {
|
public class Threads implements Runnable {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Threads test = new Threads();
|
{ Threads test = new Threads();
|
||||||
Thread thread = new Thread(test);
|
Thread thread = new Thread(test);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
synchronized (test) {
|
synchronized (test) {
|
||||||
thread.start();
|
thread.start();
|
||||||
test.wait();
|
test.wait();
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
}
|
||||||
e.printStackTrace();
|
|
||||||
|
{ Thread thread = new Thread() {
|
||||||
|
public void run() {
|
||||||
|
while (true) {
|
||||||
|
System.out.print(".");
|
||||||
|
try {
|
||||||
|
sleep(1000);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("thread interrupted? " + interrupted());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
thread.start();
|
||||||
|
|
||||||
|
System.out.println("\nAbout to interrupt...");
|
||||||
|
thread.interrupt();
|
||||||
|
System.out.println("\nInterrupted!");
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("finished");
|
System.out.println("finished");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user