diff options
author | Mathieu Chartier <mathieuc@google.com> | 2014-05-22 14:43:37 -0700 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2014-05-22 14:43:37 -0700 |
commit | a6e7f0872c42009ecbee82d7fbe452deef9ae65b (patch) | |
tree | 1ba6d026f6c9a47b9961c62511ab47c6d69314dd /runtime/monitor.cc | |
parent | 697726d42eaf804a1124c25dec58c2b0013a30e9 (diff) | |
download | art-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.cc | 4 |
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_; } |