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) 1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)DeferredSequencedTaskRunner::DeferredTask::DeferredTask() 1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : is_non_nestable(false) { 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DeferredSequencedTaskRunner::DeferredTask::~DeferredTask() { 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DeferredSequencedTaskRunner::DeferredSequencedTaskRunner( 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const scoped_refptr<SequencedTaskRunner>& target_task_runner) 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : started_(false), 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) target_task_runner_(target_task_runner) { 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DeferredSequencedTaskRunner::~DeferredSequencedTaskRunner() { 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool DeferredSequencedTaskRunner::PostDelayedTask( 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const tracked_objects::Location& from_here, 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const Closure& task, 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TimeDelta delay) { 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AutoLock lock(lock_); 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (started_) { 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(deferred_tasks_queue_.empty()); 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return target_task_runner_->PostDelayedTask(from_here, task, delay); 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QueueDeferredTask(from_here, task, delay, false /* is_non_nestable */); 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool DeferredSequencedTaskRunner::RunsTasksOnCurrentThread() const { 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return target_task_runner_->RunsTasksOnCurrentThread(); 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool DeferredSequencedTaskRunner::PostNonNestableDelayedTask( 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const tracked_objects::Location& from_here, 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const Closure& task, 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TimeDelta delay) { 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AutoLock lock(lock_); 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (started_) { 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(deferred_tasks_queue_.empty()); 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return target_task_runner_->PostNonNestableDelayedTask(from_here, 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) task, 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delay); 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QueueDeferredTask(from_here, task, delay, true /* is_non_nestable */); 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DeferredSequencedTaskRunner::QueueDeferredTask( 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const tracked_objects::Location& from_here, 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const Closure& task, 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TimeDelta delay, 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_non_nestable) { 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DeferredTask deferred_task; 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) deferred_task.posted_from = from_here; 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) deferred_task.task = task; 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) deferred_task.delay = delay; 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) deferred_task.is_non_nestable = is_non_nestable; 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) deferred_tasks_queue_.push_back(deferred_task); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DeferredSequencedTaskRunner::Start() { 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AutoLock lock(lock_); 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!started_); 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) started_ = true; 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (std::vector<DeferredTask>::iterator i = deferred_tasks_queue_.begin(); 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) i != deferred_tasks_queue_.end(); 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ++i) { 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const DeferredTask& task = *i; 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (task.is_non_nestable) { 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) target_task_runner_->PostNonNestableDelayedTask(task.posted_from, 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) task.task, 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) task.delay); 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) target_task_runner_->PostDelayedTask(task.posted_from, 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) task.task, 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) task.delay); 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Replace the i-th element in the |deferred_tasks_queue_| with an empty 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |DelayedTask| to ensure that |task| is destroyed before the next task 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // is posted. 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *i = DeferredTask(); 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) deferred_tasks_queue_.clear(); 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace base 101