summaryrefslogtreecommitdiffstats
path: root/runtime/monitor.cc
diff options
context:
space:
mode:
authorElena Sayapina <elena.v.sayapina@intel.com>2014-06-20 16:58:37 +0700
committerAndreas Gampe <agampe@google.com>2014-07-07 18:39:55 -0700
commit1af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42 (patch)
tree07807547760383cfe9310c70ea00eace03b2740b /runtime/monitor.cc
parent13f89cb9930ea799c21559020da43c3845536da5 (diff)
downloadart-1af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42.tar.gz
art-1af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42.tar.bz2
art-1af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42.zip
ART: Update Monitor::Wait so it releases monitor_lock_ before throwing an exception
Thread should release monitor_lock_ Mutex (which guards shared structures behind Java monitor) in Monitor::Wait before throwing any exception. Otherwise the thread may be suspended by GC during that time still holding the lock. This may cause deadlock during GC in case some other thread needs to acquire the monitor_lock_. The other thread can't be suspended by GC then waiting for exclusive lock and "thread suspend timeout" occurs. Change-Id: Id02f45052e1cfc01e676a43434125817564d7874 Signed-off-by: Elena Sayapina <elena.v.sayapina@intel.com>
Diffstat (limited to 'runtime/monitor.cc')
-rw-r--r--runtime/monitor.cc7
1 files changed, 4 insertions, 3 deletions
diff --git a/runtime/monitor.cc b/runtime/monitor.cc
index 999a9e504b..eb62a694e0 100644
--- a/runtime/monitor.cc
+++ b/runtime/monitor.cc
@@ -401,8 +401,8 @@ void Monitor::Wait(Thread* self, int64_t ms, int32_t ns,
// Make sure that we hold the lock.
if (owner_ != self) {
- ThrowIllegalMonitorStateExceptionF("object not locked by thread before wait()");
monitor_lock_.Unlock(self);
+ ThrowIllegalMonitorStateExceptionF("object not locked by thread before wait()");
return;
}
@@ -414,10 +414,10 @@ void Monitor::Wait(Thread* self, int64_t ms, int32_t ns,
// Enforce the timeout range.
if (ms < 0 || ns < 0 || ns > 999999) {
+ monitor_lock_.Unlock(self);
ThrowLocation throw_location = self->GetCurrentLocationForThrow();
self->ThrowNewExceptionF(throw_location, "Ljava/lang/IllegalArgumentException;",
"timeout arguments out of range: ms=%" PRId64 " ns=%d", ms, ns);
- monitor_lock_.Unlock(self);
return;
}
@@ -512,6 +512,8 @@ void Monitor::Wait(Thread* self, int64_t ms, int32_t ns,
--num_waiters_;
RemoveFromWaitSet(self);
+ monitor_lock_.Unlock(self);
+
if (was_interrupted) {
/*
* We were interrupted while waiting, or somebody interrupted an
@@ -529,7 +531,6 @@ void Monitor::Wait(Thread* self, int64_t ms, int32_t ns,
self->ThrowNewException(throw_location, "Ljava/lang/InterruptedException;", NULL);
}
}
- monitor_lock_.Unlock(self);
}
void Monitor::Notify(Thread* self) {