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:
Joel Dice 2011-07-12 14:15:43 -06:00
parent ab8e6cdc80
commit c3fa08c430
7 changed files with 81 additions and 10 deletions

View File

@ -139,9 +139,17 @@ public class Thread implements Runnable {
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() {
return currentThread().interrupted;

View File

@ -554,6 +554,15 @@ Avian_java_lang_Thread_interrupt
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
Avian_java_lang_Thread_getStackTrace
(Thread* t, object, uintptr_t* arguments)

View File

@ -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
intern(Thread* t, object s);

View File

@ -151,6 +151,16 @@ class MySystem: public System {
expect(s, rv == 0);
}
virtual bool getAndClearInterrupted() {
ACQUIRE(mutex);
bool interrupted = r->interrupted();
r->setInterrupted(false);
return interrupted;
}
virtual void join() {
int rv UNUSED = pthread_join(thread, 0);
expect(s, rv == 0);

View File

@ -30,6 +30,7 @@ class System {
class Thread {
public:
virtual void interrupt() = 0;
virtual bool getAndClearInterrupted() = 0;
virtual void join() = 0;
virtual void dispose() = 0;
};

View File

@ -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() {
int r UNUSED = WaitForSingleObject(thread, INFINITE);
assert(s, r == WAIT_OBJECT_0);

View File

@ -1,15 +1,36 @@
public class Threads implements Runnable {
public static void main(String[] args) {
Threads test = new Threads();
Thread thread = new Thread(test);
{ Threads test = new Threads();
Thread thread = new Thread(test);
try {
synchronized (test) {
thread.start();
test.wait();
try {
synchronized (test) {
thread.start();
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");