From e6afc6c321181871ac4a0b707d40e3ebc2490e5b Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 2 May 2012 11:41:36 -0600 Subject: [PATCH] set Thread.interrupted to true if thread is interrupted outside wait or sleep This is the correct behavior according to the Thread.interrupt JavaDoc, and it fixes an intermittent hang on exit in Eclipse. --- src/classpath-avian.cpp | 6 ++++++ src/classpath-openjdk.cpp | 20 ++++++++++++++++++-- src/machine.h | 4 ++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/classpath-avian.cpp b/src/classpath-avian.cpp index 39cde4ff83..5df85fa6b6 100644 --- a/src/classpath-avian.cpp +++ b/src/classpath-avian.cpp @@ -54,6 +54,12 @@ class MyClasspath : public Classpath { root(t, Machine::BootLoader), 0, 0, group, 0); } + virtual void + clearInterrupted(Thread*) + { + // ignore + } + virtual void runThread(Thread* t) { diff --git a/src/classpath-openjdk.cpp b/src/classpath-openjdk.cpp index 78cb98083a..721889e452 100644 --- a/src/classpath-openjdk.cpp +++ b/src/classpath-openjdk.cpp @@ -344,6 +344,9 @@ makeClassNameString(Thread* t, object name) void interceptFileOperations(Thread*); +void +clearInterrupted(Thread*); + class MyClasspath : public Classpath { public: static const unsigned BufferSize = 1024; @@ -506,6 +509,12 @@ class MyClasspath : public Classpath { return thread; } + virtual void + clearInterrupted(Thread* t) + { + local::clearInterrupted(t); + } + virtual void runThread(Thread* t) { @@ -2212,6 +2221,14 @@ interruptLock(Thread* t, object thread) return threadInterruptLock(t, thread); } +void +clearInterrupted(Thread* t) +{ + monitorAcquire(t, local::interruptLock(t, t->javaThread)); + threadInterrupted(t, t->javaThread) = false; + monitorRelease(t, local::interruptLock(t, t->javaThread)); +} + bool pipeAvailable(int fd, int* available) { @@ -3350,9 +3367,8 @@ jvmInterrupt(Thread* t, uintptr_t* arguments) Thread* p = reinterpret_cast(threadPeer(t, *thread)); if (p) { interrupt(t, p); - } else { - threadInterrupted(t, *thread) = true; } + threadInterrupted(t, *thread) = true; monitorRelease(t, local::interruptLock(t, *thread)); return 1; diff --git a/src/machine.h b/src/machine.h index cdb3ecf039..eea9cc506b 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1577,6 +1577,9 @@ class Classpath { virtual object makeThread(Thread* t, Thread* parent) = 0; + virtual void + clearInterrupted(Thread* t) = 0; + virtual void runThread(Thread* t) = 0; @@ -3215,6 +3218,7 @@ wait(Thread* t, object o, int64_t milliseconds) if (interrupted) { if (t->m->alive or (t->flags & Thread::DaemonFlag) == 0) { + t->m->classpath->clearInterrupted(t); throwNew(t, Machine::InterruptedExceptionType); } else { throw_(t, root(t, Machine::Shutdown));