diff options
| author | 2016-03-10 20:07:55 +0000 | |
|---|---|---|
| committer | 2016-03-10 20:07:55 +0000 | |
| commit | 3d63118460dbcff330cb188ea86bd5ad5cda5f99 (patch) | |
| tree | 9ddae34ed391298d6deb20b76b2c925a54cd538b | |
| parent | 7aedfdb232f167300cd8e3322e193eee6f433061 (diff) | |
| parent | daed5d81e2fdb9d1e03ee6c34567347b92dcfb22 (diff) | |
Merge "Allocate interrupted exception before re-acquiring lock"
| -rw-r--r-- | runtime/monitor.cc | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/runtime/monitor.cc b/runtime/monitor.cc index 1ce5841bed..a262c7a8f3 100644 --- a/runtime/monitor.cc +++ b/runtime/monitor.cc @@ -497,6 +497,24 @@ void Monitor::Wait(Thread* self, int64_t ms, int32_t ns, self->SetWaitMonitor(nullptr); } + // Allocate the interrupted exception not holding the monitor lock since it may cause a GC. + // If the GC requires acquiring the monitor for enqueuing cleared references, this would + // cause a deadlock if the monitor is held. + if (was_interrupted && interruptShouldThrow) { + /* + * We were interrupted while waiting, or somebody interrupted an + * un-interruptible thread earlier and we're bailing out immediately. + * + * The doc sayeth: "The interrupted status of the current thread is + * cleared when this exception is thrown." + */ + { + MutexLock mu(self, *self->GetWaitMutex()); + self->SetInterruptedLocked(false); + } + self->ThrowNewException("Ljava/lang/InterruptedException;", nullptr); + } + // Re-acquire the monitor and lock. Lock(self); monitor_lock_.Lock(self); @@ -516,21 +534,6 @@ void Monitor::Wait(Thread* self, int64_t ms, int32_t ns, RemoveFromWaitSet(self); monitor_lock_.Unlock(self); - - if (was_interrupted && interruptShouldThrow) { - /* - * We were interrupted while waiting, or somebody interrupted an - * un-interruptible thread earlier and we're bailing out immediately. - * - * The doc sayeth: "The interrupted status of the current thread is - * cleared when this exception is thrown." - */ - { - MutexLock mu(self, *self->GetWaitMutex()); - self->SetInterruptedLocked(false); - } - self->ThrowNewException("Ljava/lang/InterruptedException;", nullptr); - } } void Monitor::Notify(Thread* self) { |