1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/deferred_sequenced_task_runner.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace base { 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DeferredSequencedTaskRunner::DeferredTask::DeferredTask() { 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DeferredSequencedTaskRunner::DeferredTask::~DeferredTask() { 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DeferredSequencedTaskRunner::DeferredSequencedTaskRunner( 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const scoped_refptr<SequencedTaskRunner>& target_task_runner) 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : started_(false), 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) target_task_runner_(target_task_runner) { 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DeferredSequencedTaskRunner::~DeferredSequencedTaskRunner() { 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool DeferredSequencedTaskRunner::PostDelayedTask( 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const tracked_objects::Location& from_here, 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const Closure& task, 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TimeDelta delay) { 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AutoLock lock(lock_); 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (started_) { 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(deferred_tasks_queue_.empty()); 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return target_task_runner_->PostDelayedTask(from_here, task, delay); 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QueueDeferredTask(from_here, task, delay, false /* is_non_nestable */); 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool DeferredSequencedTaskRunner::RunsTasksOnCurrentThread() const { 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return target_task_runner_->RunsTasksOnCurrentThread(); 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool DeferredSequencedTaskRunner::PostNonNestableDelayedTask( 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const tracked_objects::Location& from_here, 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const Closure& task, 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TimeDelta delay) { 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AutoLock lock(lock_); 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (started_) { 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(deferred_tasks_queue_.empty()); 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return target_task_runner_->PostNonNestableDelayedTask(from_here, 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) task, 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delay); 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QueueDeferredTask(from_here, task, delay, true /* is_non_nestable */); 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DeferredSequencedTaskRunner::QueueDeferredTask( 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const tracked_objects::Location& from_here, 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const Closure& task, 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TimeDelta delay, 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_non_nestable) { 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DeferredTask deferred_task; 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) deferred_task.posted_from = from_here; 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) deferred_task.task = task; 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) deferred_task.delay = delay; 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) deferred_task.is_non_nestable = is_non_nestable; 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) deferred_tasks_queue_.push_back(deferred_task); 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DeferredSequencedTaskRunner::Start() { 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AutoLock lock(lock_); 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!started_); 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) started_ = true; 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (std::vector<DeferredTask>::iterator i = deferred_tasks_queue_.begin(); 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) i != deferred_tasks_queue_.end(); 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ++i) { 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const DeferredTask& task = *i; 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (task.is_non_nestable) { 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) target_task_runner_->PostNonNestableDelayedTask(task.posted_from, 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) task.task, 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) task.delay); 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) target_task_runner_->PostDelayedTask(task.posted_from, 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) task.task, 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) task.delay); 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Replace the i-th element in the |deferred_tasks_queue_| with an empty 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |DelayedTask| to ensure that |task| is destroyed before the next task 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // is posted. 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *i = DeferredTask(); 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) deferred_tasks_queue_.clear(); 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace base 100