summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
author Mathieu Chartier <mathieuc@google.com> 2012-10-31 16:56:18 -0700
committer Mathieu Chartier <mathieuc@google.com> 2012-10-31 16:56:18 -0700
commite46cd75f182a3d738c5e2ef3cc90b2f0b1de56ee (patch)
treeffd976fbc1195cddbb956f87a73d423d611b3cf9 /src
parent332f6827edf72f9b3d247a6c2fa79e4d520a409d (diff)
Fix race condition in thread pool shutdown
We were not holding the task queue lock when we did broadcast, causing a race where a thread waits on the CV after the broadcast. Fixes dex2oat deadlocking. Change-Id: I84f30020511c2bd43f71d9b7b392720bd8d03eab
Diffstat (limited to 'src')
-rw-r--r--src/mutex.cc1
-rw-r--r--src/thread_pool.cc14
2 files changed, 10 insertions, 5 deletions
diff --git a/src/mutex.cc b/src/mutex.cc
index a4347ba6d2..0e33f3cc48 100644
--- a/src/mutex.cc
+++ b/src/mutex.cc
@@ -749,6 +749,7 @@ void ConditionVariable::Broadcast(Thread* self) {
DCHECK(self == NULL || self == Thread::Current());
// TODO: enable below, there's a race in thread creation that causes false failures currently.
// guard_.AssertExclusiveHeld(self);
+ DCHECK_EQ(guard_.GetExclusiveOwnerTid(), SafeGetTid(self));
#if ART_USE_FUTEXES
if (num_waiters_ > 0) {
android_atomic_inc(&state_); // Indicate a wake has occurred to waiters coming in.
diff --git a/src/thread_pool.cc b/src/thread_pool.cc
index fa0cf794c4..f3319e2d40 100644
--- a/src/thread_pool.cc
+++ b/src/thread_pool.cc
@@ -69,11 +69,15 @@ ThreadPool::ThreadPool(size_t num_threads)
}
ThreadPool::~ThreadPool() {
- // Tell any remaining workers to shut down.
- shutting_down_ = true;
- android_memory_barrier();
- // Broadcast to everyone waiting.
- task_queue_condition_.Broadcast(Thread::Current());
+ {
+ Thread* self = Thread::Current();
+ MutexLock mu(self, task_queue_lock_);
+ // Tell any remaining workers to shut down.
+ shutting_down_ = true;
+ android_memory_barrier();
+ // Broadcast to everyone waiting.
+ task_queue_condition_.Broadcast(self);
+ }
// Wait for the threads to finish.
STLDeleteElements(&threads_);
}