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