| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "platform/scheduler/base/task_queue_manager.h" | 5 #include "platform/scheduler/base/task_queue_manager.h" |
| 6 | 6 |
| 7 #include <queue> | 7 #include <queue> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 if (from_main_thread) { | 224 if (from_main_thread) { |
| 225 main_thread_pending_wakeups_.erase(run_time); | 225 main_thread_pending_wakeups_.erase(run_time); |
| 226 } else { | 226 } else { |
| 227 base::AutoLock lock(other_thread_lock_); | 227 base::AutoLock lock(other_thread_lock_); |
| 228 other_thread_pending_wakeup_ = false; | 228 other_thread_pending_wakeup_ = false; |
| 229 } | 229 } |
| 230 | 230 |
| 231 // Posting a DoWork while a DoWork is running leads to spurious DoWorks. | 231 // Posting a DoWork while a DoWork is running leads to spurious DoWorks. |
| 232 main_thread_pending_wakeups_.insert(base::TimeTicks()); | 232 main_thread_pending_wakeups_.insert(base::TimeTicks()); |
| 233 | 233 |
| 234 if (!delegate_->IsNested()) | 234 bool is_nested = delegate_->IsNested(); |
| 235 if (!is_nested) |
| 235 queues_to_delete_.clear(); | 236 queues_to_delete_.clear(); |
| 236 | 237 |
| 237 LazyNow lazy_now(real_time_domain()->CreateLazyNow()); | 238 LazyNow lazy_now(real_time_domain()->CreateLazyNow()); |
| 238 UpdateWorkQueues(&lazy_now); | 239 UpdateWorkQueues(&lazy_now); |
| 239 | 240 |
| 240 for (int i = 0; i < work_batch_size_; i++) { | 241 for (int i = 0; i < work_batch_size_; i++) { |
| 241 internal::WorkQueue* work_queue; | 242 internal::WorkQueue* work_queue; |
| 242 if (!SelectWorkQueueToService(&work_queue)) | 243 if (!SelectWorkQueueToService(&work_queue)) |
| 243 break; | 244 break; |
| 244 | 245 |
| 245 base::TimeTicks time_after_task; | 246 base::TimeTicks time_after_task; |
| 246 switch (ProcessTaskFromWorkQueue(work_queue, lazy_now, &time_after_task)) { | 247 switch (ProcessTaskFromWorkQueue(work_queue, is_nested, lazy_now, |
| 248 &time_after_task)) { |
| 247 case ProcessTaskResult::DEFERRED: | 249 case ProcessTaskResult::DEFERRED: |
| 248 // If a task was deferred, try again with another task. | 250 // If a task was deferred, try again with another task. |
| 249 continue; | 251 continue; |
| 250 case ProcessTaskResult::EXECUTED: | 252 case ProcessTaskResult::EXECUTED: |
| 251 break; | 253 break; |
| 252 case ProcessTaskResult::TASK_QUEUE_MANAGER_DELETED: | 254 case ProcessTaskResult::TASK_QUEUE_MANAGER_DELETED: |
| 253 return; // The TaskQueueManager got deleted, we must bail out. | 255 return; // The TaskQueueManager got deleted, we must bail out. |
| 254 } | 256 } |
| 255 | 257 |
| 256 work_queue = nullptr; // The queue may have been unregistered. | 258 work_queue = nullptr; // The queue may have been unregistered. |
| 257 | 259 |
| 258 lazy_now = time_after_task.is_null() ? real_time_domain()->CreateLazyNow() | 260 lazy_now = time_after_task.is_null() ? real_time_domain()->CreateLazyNow() |
| 259 : LazyNow(time_after_task); | 261 : LazyNow(time_after_task); |
| 260 UpdateWorkQueues(&lazy_now); | 262 UpdateWorkQueues(&lazy_now); |
| 261 | 263 |
| 262 // Only run a single task per batch in nested run loops so that we can | 264 // Only run a single task per batch in nested run loops so that we can |
| 263 // properly exit the nested loop when someone calls RunLoop::Quit(). | 265 // properly exit the nested loop when someone calls RunLoop::Quit(). |
| 264 if (delegate_->IsNested()) | 266 if (is_nested) |
| 265 break; | 267 break; |
| 266 } | 268 } |
| 267 | 269 |
| 268 main_thread_pending_wakeups_.erase(base::TimeTicks()); | 270 main_thread_pending_wakeups_.erase(base::TimeTicks()); |
| 269 | 271 |
| 270 // TODO(alexclarke): Consider refactoring the above loop to terminate only | 272 // TODO(alexclarke): Consider refactoring the above loop to terminate only |
| 271 // when there's no more work left to be done, rather than posting a | 273 // when there's no more work left to be done, rather than posting a |
| 272 // continuation task. | 274 // continuation task. |
| 273 base::Optional<base::TimeDelta> next_delay = | 275 base::Optional<base::TimeDelta> next_delay = |
| 274 ComputeDelayTillNextTask(&lazy_now); | 276 ComputeDelayTillNextTask(&lazy_now); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 return should_run; | 315 return should_run; |
| 314 } | 316 } |
| 315 | 317 |
| 316 void TaskQueueManager::DidQueueTask( | 318 void TaskQueueManager::DidQueueTask( |
| 317 const internal::TaskQueueImpl::Task& pending_task) { | 319 const internal::TaskQueueImpl::Task& pending_task) { |
| 318 task_annotator_.DidQueueTask("TaskQueueManager::PostTask", pending_task); | 320 task_annotator_.DidQueueTask("TaskQueueManager::PostTask", pending_task); |
| 319 } | 321 } |
| 320 | 322 |
| 321 TaskQueueManager::ProcessTaskResult TaskQueueManager::ProcessTaskFromWorkQueue( | 323 TaskQueueManager::ProcessTaskResult TaskQueueManager::ProcessTaskFromWorkQueue( |
| 322 internal::WorkQueue* work_queue, | 324 internal::WorkQueue* work_queue, |
| 325 bool is_nested, |
| 323 LazyNow time_before_task, | 326 LazyNow time_before_task, |
| 324 base::TimeTicks* time_after_task) { | 327 base::TimeTicks* time_after_task) { |
| 325 DCHECK(main_thread_checker_.CalledOnValidThread()); | 328 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 326 scoped_refptr<DeletionSentinel> protect(deletion_sentinel_); | 329 scoped_refptr<DeletionSentinel> protect(deletion_sentinel_); |
| 327 internal::TaskQueueImpl::Task pending_task = | 330 internal::TaskQueueImpl::Task pending_task = |
| 328 work_queue->TakeTaskFromWorkQueue(); | 331 work_queue->TakeTaskFromWorkQueue(); |
| 329 | 332 |
| 330 // It's possible the task was canceled, if so bail out. | 333 // It's possible the task was canceled, if so bail out. |
| 331 if (pending_task.task.IsCancelled()) | 334 if (pending_task.task.IsCancelled()) |
| 332 return ProcessTaskResult::EXECUTED; | 335 return ProcessTaskResult::EXECUTED; |
| 333 | 336 |
| 334 internal::TaskQueueImpl* queue = work_queue->task_queue(); | 337 internal::TaskQueueImpl* queue = work_queue->task_queue(); |
| 335 if (queue->GetQuiescenceMonitored()) | 338 if (queue->GetQuiescenceMonitored()) |
| 336 task_was_run_on_quiescence_monitored_queue_ = true; | 339 task_was_run_on_quiescence_monitored_queue_ = true; |
| 337 | 340 |
| 338 if (!pending_task.nestable && delegate_->IsNested()) { | 341 if (!pending_task.nestable && is_nested) { |
| 339 // Defer non-nestable work to the main task runner. NOTE these tasks can be | 342 // Defer non-nestable work to the main task runner. NOTE these tasks can be |
| 340 // arbitrarily delayed so the additional delay should not be a problem. | 343 // arbitrarily delayed so the additional delay should not be a problem. |
| 341 // TODO(skyostil): Figure out a way to not forget which task queue the | 344 // TODO(skyostil): Figure out a way to not forget which task queue the |
| 342 // task is associated with. See http://crbug.com/522843. | 345 // task is associated with. See http://crbug.com/522843. |
| 343 // TODO(tzik): Remove base::UnsafeConvertOnceClosureToRepeating once | 346 // TODO(tzik): Remove base::UnsafeConvertOnceClosureToRepeating once |
| 344 // TaskRunners have migrated to OnceClosure. | 347 // TaskRunners have migrated to OnceClosure. |
| 345 delegate_->PostNonNestableTask( | 348 delegate_->PostNonNestableTask( |
| 346 pending_task.posted_from, | 349 pending_task.posted_from, |
| 347 UnsafeConvertOnceClosureToRepeating(std::move(pending_task.task))); | 350 UnsafeConvertOnceClosureToRepeating(std::move(pending_task.task))); |
| 348 return ProcessTaskResult::DEFERRED; | 351 return ProcessTaskResult::DEFERRED; |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 for (const scoped_refptr<internal::TaskQueueImpl>& queue : queues_) { | 539 for (const scoped_refptr<internal::TaskQueueImpl>& queue : queues_) { |
| 537 TimeDomain* time_domain = queue->GetTimeDomain(); | 540 TimeDomain* time_domain = queue->GetTimeDomain(); |
| 538 if (time_domain_now.find(time_domain) == time_domain_now.end()) | 541 if (time_domain_now.find(time_domain) == time_domain_now.end()) |
| 539 time_domain_now.insert(std::make_pair(time_domain, time_domain->Now())); | 542 time_domain_now.insert(std::make_pair(time_domain, time_domain->Now())); |
| 540 queue->SweepCanceledDelayedTasks(time_domain_now[time_domain]); | 543 queue->SweepCanceledDelayedTasks(time_domain_now[time_domain]); |
| 541 } | 544 } |
| 542 } | 545 } |
| 543 | 546 |
| 544 } // namespace scheduler | 547 } // namespace scheduler |
| 545 } // namespace blink | 548 } // namespace blink |
| OLD | NEW |