| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/task_scheduler/scheduler_worker.h" | 5 #include "base/task_scheduler/scheduler_worker.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 if (thread->thread_handle_.is_null()) | 29 if (thread->thread_handle_.is_null()) |
| 30 return nullptr; | 30 return nullptr; |
| 31 return thread; | 31 return thread; |
| 32 } | 32 } |
| 33 | 33 |
| 34 // PlatformThread::Delegate. | 34 // PlatformThread::Delegate. |
| 35 void ThreadMain() override { | 35 void ThreadMain() override { |
| 36 // Set if this thread was detached. | 36 // Set if this thread was detached. |
| 37 std::unique_ptr<Thread> detached_thread; | 37 std::unique_ptr<Thread> detached_thread; |
| 38 | 38 |
| 39 outer_->delegate_->OnMainEntry( | 39 outer_->delegate_->OnMainEntry(outer_); |
| 40 outer_, outer_->last_detach_time_.is_null() | |
| 41 ? TimeDelta::Max() | |
| 42 : TimeTicks::Now() - outer_->last_detach_time_); | |
| 43 | 40 |
| 44 // A SchedulerWorker starts out waiting for work. | 41 // A SchedulerWorker starts out waiting for work. |
| 45 WaitForWork(); | 42 WaitForWork(); |
| 46 | 43 |
| 47 while (!outer_->task_tracker_->IsShutdownComplete() && | 44 while (!outer_->task_tracker_->IsShutdownComplete() && |
| 48 !outer_->should_exit_for_testing_.IsSet()) { | 45 !outer_->should_exit_for_testing_.IsSet()) { |
| 49 DCHECK(outer_); | 46 DCHECK(outer_); |
| 50 | 47 |
| 51 #if defined(OS_MACOSX) | 48 #if defined(OS_MACOSX) |
| 52 mac::ScopedNSAutoreleasePool autorelease_pool; | 49 mac::ScopedNSAutoreleasePool autorelease_pool; |
| 53 #endif | 50 #endif |
| 54 | 51 |
| 55 UpdateThreadPriority(GetDesiredThreadPriority()); | 52 UpdateThreadPriority(GetDesiredThreadPriority()); |
| 56 | 53 |
| 57 // Get the sequence containing the next task to execute. | 54 // Get the sequence containing the next task to execute. |
| 58 scoped_refptr<Sequence> sequence = outer_->delegate_->GetWork(outer_); | 55 scoped_refptr<Sequence> sequence = outer_->delegate_->GetWork(outer_); |
| 59 if (!sequence) { | 56 if (!sequence) { |
| 60 if (outer_->delegate_->CanDetach(outer_)) { | 57 if (outer_->delegate_->CanDetach(outer_)) { |
| 61 detached_thread = outer_->Detach(); | 58 detached_thread = outer_->Detach(); |
| 62 if (detached_thread) { | 59 if (detached_thread) { |
| 60 outer_ = nullptr; |
| 63 DCHECK_EQ(detached_thread.get(), this); | 61 DCHECK_EQ(detached_thread.get(), this); |
| 64 PlatformThread::Detach(thread_handle_); | 62 PlatformThread::Detach(thread_handle_); |
| 65 outer_ = nullptr; | |
| 66 break; | 63 break; |
| 67 } | 64 } |
| 68 } | 65 } |
| 69 WaitForWork(); | 66 WaitForWork(); |
| 70 continue; | 67 continue; |
| 71 } | 68 } |
| 72 | 69 |
| 73 std::unique_ptr<Task> task = sequence->TakeTask(); | 70 std::unique_ptr<Task> task = sequence->TakeTask(); |
| 74 const TaskPriority task_priority = task->traits.priority(); | 71 const TaskPriority task_priority = task->traits.priority(); |
| 75 const TimeDelta task_latency = TimeTicks::Now() - task->sequenced_time; | 72 const TimeDelta task_latency = TimeTicks::Now() - task->sequenced_time; |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 } | 248 } |
| 252 | 249 |
| 253 std::unique_ptr<SchedulerWorker::Thread> SchedulerWorker::Detach() { | 250 std::unique_ptr<SchedulerWorker::Thread> SchedulerWorker::Detach() { |
| 254 DCHECK(!should_exit_for_testing_.IsSet()) << "Worker was already joined"; | 251 DCHECK(!should_exit_for_testing_.IsSet()) << "Worker was already joined"; |
| 255 AutoSchedulerLock auto_lock(thread_lock_); | 252 AutoSchedulerLock auto_lock(thread_lock_); |
| 256 // If a wakeup is pending, then a WakeUp() came in while we were deciding to | 253 // If a wakeup is pending, then a WakeUp() came in while we were deciding to |
| 257 // detach. This means we can't go away anymore since we would break the | 254 // detach. This means we can't go away anymore since we would break the |
| 258 // guarantee that we call GetWork() after a successful wakeup. | 255 // guarantee that we call GetWork() after a successful wakeup. |
| 259 if (thread_->IsWakeUpPending()) | 256 if (thread_->IsWakeUpPending()) |
| 260 return nullptr; | 257 return nullptr; |
| 261 last_detach_time_ = TimeTicks::Now(); | 258 |
| 259 // Call OnDetach() within the scope of |thread_lock_| to prevent the delegate |
| 260 // from being used concurrently from an old and a new thread. |
| 261 delegate_->OnDetach(); |
| 262 |
| 262 return std::move(thread_); | 263 return std::move(thread_); |
| 263 } | 264 } |
| 264 | 265 |
| 265 void SchedulerWorker::CreateThread() { | 266 void SchedulerWorker::CreateThread() { |
| 266 thread_ = Thread::Create(this); | 267 thread_ = Thread::Create(this); |
| 267 } | 268 } |
| 268 | 269 |
| 269 void SchedulerWorker::CreateThreadAssertSynchronized() { | 270 void SchedulerWorker::CreateThreadAssertSynchronized() { |
| 270 thread_lock_.AssertAcquired(); | 271 thread_lock_.AssertAcquired(); |
| 271 CreateThread(); | 272 CreateThread(); |
| 272 } | 273 } |
| 273 | 274 |
| 274 } // namespace internal | 275 } // namespace internal |
| 275 } // namespace base | 276 } // namespace base |
| OLD | NEW |