Chromium Code Reviews| Index: base/task_scheduler/scheduler_worker.cc |
| diff --git a/base/task_scheduler/scheduler_worker.cc b/base/task_scheduler/scheduler_worker.cc |
| index 970a7d4cf908a9b4aa8249f988e1ebeaed1e41ba..f430cc01607ae940bff899f7f02c6432a588ca50 100644 |
| --- a/base/task_scheduler/scheduler_worker.cc |
| +++ b/base/task_scheduler/scheduler_worker.cc |
| @@ -216,6 +216,9 @@ SchedulerWorker::~SchedulerWorker() { |
| void SchedulerWorker::WakeUp() { |
| AutoSchedulerLock auto_lock(thread_lock_); |
| + |
| + DCHECK(!should_exit_for_testing_.IsSet()); |
| + |
| if (!thread_) |
| CreateThreadAssertSynchronized(); |
| @@ -227,17 +230,21 @@ void SchedulerWorker::JoinForTesting() { |
| DCHECK(!should_exit_for_testing_.IsSet()); |
| should_exit_for_testing_.Set(); |
| - WakeUp(); |
| + std::unique_ptr<Thread> thread; |
| - // Normally holding a lock and joining is dangerous. However, since this is |
| - // only for testing, we're okay since the only scenario that could impact this |
| - // is a call to Detach, which is disallowed by having the delegate always |
| - // return false for the CanDetach call. |
| - AutoSchedulerLock auto_lock(thread_lock_); |
| - if (thread_) |
| - thread_->Join(); |
| + { |
| + AutoSchedulerLock auto_lock(thread_lock_); |
| + |
| + if (thread_) { |
| + // Wake-up the thread. It will see that |should_exit_for_testing_| is set |
|
gab
2017/01/17 21:24:25
s/Wake-up the thread/Make sure the thread is awake
fdoray
2017/01/17 23:51:00
Done.
|
| + // and exit sortly after. |
|
gab
2017/01/17 21:24:25
s/sortly/shortly/
fdoray
2017/01/17 23:51:00
Done.
|
| + thread_->WakeUp(); |
| + thread = std::move(thread_); |
| + } |
| + } |
| - thread_.reset(); |
| + if (thread) |
| + thread->Join(); |
| } |
| bool SchedulerWorker::ThreadAliveForTesting() const { |
| @@ -256,8 +263,14 @@ SchedulerWorker::SchedulerWorker(ThreadPriority priority_hint, |
| } |
| std::unique_ptr<SchedulerWorker::Thread> SchedulerWorker::Detach() { |
| - DCHECK(!should_exit_for_testing_.IsSet()) << "Worker was already joined"; |
| AutoSchedulerLock auto_lock(thread_lock_); |
| + |
| + // Do not detach if the thread is being joined. |
| + if (!thread_) { |
| + DCHECK(should_exit_for_testing_.IsSet()); |
| + return nullptr; |
| + } |
| + |
| // If a wakeup is pending, then a WakeUp() came in while we were deciding to |
| // detach. This means we can't go away anymore since we would break the |
| // guarantee that we call GetWork() after a successful wakeup. |