summaryrefslogtreecommitdiffstats
path: root/runtime/monitor.cc
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2014-05-22 14:43:37 -0700
committerMathieu Chartier <mathieuc@google.com>2014-05-22 14:43:37 -0700
commita6e7f0872c42009ecbee82d7fbe452deef9ae65b (patch)
tree1ba6d026f6c9a47b9961c62511ab47c6d69314dd /runtime/monitor.cc
parent697726d42eaf804a1124c25dec58c2b0013a30e9 (diff)
downloadart-a6e7f0872c42009ecbee82d7fbe452deef9ae65b.tar.gz
art-a6e7f0872c42009ecbee82d7fbe452deef9ae65b.tar.bz2
art-a6e7f0872c42009ecbee82d7fbe452deef9ae65b.zip
Move SetMonitorEnterObject outside of blocked thread state change.
Race condition: Thread is suspended in monitor kBlocked, GC decides to run the checkpoint on it. The GC sees that the object is non null, and goes to mark it, but then the thread does SetMonitorObject(nullptr). Which causes a null object to be marked. Change-Id: Ie8a5074112947ec07d01ccb813ca2c1bb9ac7066
Diffstat (limited to 'runtime/monitor.cc')
-rw-r--r--runtime/monitor.cc4
1 files changed, 2 insertions, 2 deletions
diff --git a/runtime/monitor.cc b/runtime/monitor.cc
index cc38c59543..4a4dffb938 100644
--- a/runtime/monitor.cc
+++ b/runtime/monitor.cc
@@ -226,9 +226,9 @@ void Monitor::Lock(Thread* self) {
// Do this before releasing the lock so that we don't get deflated.
++num_waiters_;
monitor_lock_.Unlock(self); // Let go of locks in order.
+ self->SetMonitorEnterObject(GetObject());
{
ScopedThreadStateChange tsc(self, kBlocked); // Change to blocked and give up mutator_lock_.
- self->SetMonitorEnterObject(GetObject());
MutexLock mu2(self, monitor_lock_); // Reacquire monitor_lock_ without mutator_lock_ for Wait.
if (owner_ != NULL) { // Did the owner_ give the lock up?
monitor_contenders_.Wait(self); // Still contended so wait.
@@ -249,8 +249,8 @@ void Monitor::Lock(Thread* self) {
}
}
}
- self->SetMonitorEnterObject(nullptr);
}
+ self->SetMonitorEnterObject(nullptr);
monitor_lock_.Lock(self); // Reacquire locks in order.
--num_waiters_;
}