summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mathieu Chartier <mathieuc@google.com> 2016-03-10 20:07:55 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2016-03-10 20:07:55 +0000
commit3d63118460dbcff330cb188ea86bd5ad5cda5f99 (patch)
tree9ddae34ed391298d6deb20b76b2c925a54cd538b
parent7aedfdb232f167300cd8e3322e193eee6f433061 (diff)
parentdaed5d81e2fdb9d1e03ee6c34567347b92dcfb22 (diff)
Merge "Allocate interrupted exception before re-acquiring lock"
-rw-r--r--runtime/monitor.cc33
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) {