1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "base/deferred_sequenced_task_runner.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <utility>
8*635a8641SAndroid Build Coastguard Worker
9*635a8641SAndroid Build Coastguard Worker #include "base/bind.h"
10*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
11*635a8641SAndroid Build Coastguard Worker
12*635a8641SAndroid Build Coastguard Worker namespace base {
13*635a8641SAndroid Build Coastguard Worker
DeferredTask()14*635a8641SAndroid Build Coastguard Worker DeferredSequencedTaskRunner::DeferredTask::DeferredTask()
15*635a8641SAndroid Build Coastguard Worker : is_non_nestable(false) {
16*635a8641SAndroid Build Coastguard Worker }
17*635a8641SAndroid Build Coastguard Worker
18*635a8641SAndroid Build Coastguard Worker DeferredSequencedTaskRunner::DeferredTask::DeferredTask(DeferredTask&& other) =
19*635a8641SAndroid Build Coastguard Worker default;
20*635a8641SAndroid Build Coastguard Worker
21*635a8641SAndroid Build Coastguard Worker DeferredSequencedTaskRunner::DeferredTask::~DeferredTask() = default;
22*635a8641SAndroid Build Coastguard Worker
23*635a8641SAndroid Build Coastguard Worker DeferredSequencedTaskRunner::DeferredTask&
24*635a8641SAndroid Build Coastguard Worker DeferredSequencedTaskRunner::DeferredTask::operator=(DeferredTask&& other) =
25*635a8641SAndroid Build Coastguard Worker default;
26*635a8641SAndroid Build Coastguard Worker
DeferredSequencedTaskRunner(scoped_refptr<SequencedTaskRunner> target_task_runner)27*635a8641SAndroid Build Coastguard Worker DeferredSequencedTaskRunner::DeferredSequencedTaskRunner(
28*635a8641SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> target_task_runner)
29*635a8641SAndroid Build Coastguard Worker : DeferredSequencedTaskRunner() {
30*635a8641SAndroid Build Coastguard Worker DCHECK(target_task_runner);
31*635a8641SAndroid Build Coastguard Worker target_task_runner_ = std::move(target_task_runner);
32*635a8641SAndroid Build Coastguard Worker }
33*635a8641SAndroid Build Coastguard Worker
DeferredSequencedTaskRunner()34*635a8641SAndroid Build Coastguard Worker DeferredSequencedTaskRunner::DeferredSequencedTaskRunner()
35*635a8641SAndroid Build Coastguard Worker : created_thread_id_(PlatformThread::CurrentId()) {}
36*635a8641SAndroid Build Coastguard Worker
PostDelayedTask(const Location & from_here,OnceClosure task,TimeDelta delay)37*635a8641SAndroid Build Coastguard Worker bool DeferredSequencedTaskRunner::PostDelayedTask(const Location& from_here,
38*635a8641SAndroid Build Coastguard Worker OnceClosure task,
39*635a8641SAndroid Build Coastguard Worker TimeDelta delay) {
40*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
41*635a8641SAndroid Build Coastguard Worker if (started_) {
42*635a8641SAndroid Build Coastguard Worker DCHECK(deferred_tasks_queue_.empty());
43*635a8641SAndroid Build Coastguard Worker return target_task_runner_->PostDelayedTask(from_here, std::move(task),
44*635a8641SAndroid Build Coastguard Worker delay);
45*635a8641SAndroid Build Coastguard Worker }
46*635a8641SAndroid Build Coastguard Worker
47*635a8641SAndroid Build Coastguard Worker QueueDeferredTask(from_here, std::move(task), delay,
48*635a8641SAndroid Build Coastguard Worker false /* is_non_nestable */);
49*635a8641SAndroid Build Coastguard Worker return true;
50*635a8641SAndroid Build Coastguard Worker }
51*635a8641SAndroid Build Coastguard Worker
RunsTasksInCurrentSequence() const52*635a8641SAndroid Build Coastguard Worker bool DeferredSequencedTaskRunner::RunsTasksInCurrentSequence() const {
53*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
54*635a8641SAndroid Build Coastguard Worker if (target_task_runner_)
55*635a8641SAndroid Build Coastguard Worker return target_task_runner_->RunsTasksInCurrentSequence();
56*635a8641SAndroid Build Coastguard Worker
57*635a8641SAndroid Build Coastguard Worker return created_thread_id_ == PlatformThread::CurrentId();
58*635a8641SAndroid Build Coastguard Worker }
59*635a8641SAndroid Build Coastguard Worker
PostNonNestableDelayedTask(const Location & from_here,OnceClosure task,TimeDelta delay)60*635a8641SAndroid Build Coastguard Worker bool DeferredSequencedTaskRunner::PostNonNestableDelayedTask(
61*635a8641SAndroid Build Coastguard Worker const Location& from_here,
62*635a8641SAndroid Build Coastguard Worker OnceClosure task,
63*635a8641SAndroid Build Coastguard Worker TimeDelta delay) {
64*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
65*635a8641SAndroid Build Coastguard Worker if (started_) {
66*635a8641SAndroid Build Coastguard Worker DCHECK(deferred_tasks_queue_.empty());
67*635a8641SAndroid Build Coastguard Worker return target_task_runner_->PostNonNestableDelayedTask(
68*635a8641SAndroid Build Coastguard Worker from_here, std::move(task), delay);
69*635a8641SAndroid Build Coastguard Worker }
70*635a8641SAndroid Build Coastguard Worker QueueDeferredTask(from_here, std::move(task), delay,
71*635a8641SAndroid Build Coastguard Worker true /* is_non_nestable */);
72*635a8641SAndroid Build Coastguard Worker return true;
73*635a8641SAndroid Build Coastguard Worker }
74*635a8641SAndroid Build Coastguard Worker
Start()75*635a8641SAndroid Build Coastguard Worker void DeferredSequencedTaskRunner::Start() {
76*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
77*635a8641SAndroid Build Coastguard Worker StartImpl();
78*635a8641SAndroid Build Coastguard Worker }
79*635a8641SAndroid Build Coastguard Worker
StartWithTaskRunner(scoped_refptr<SequencedTaskRunner> target_task_runner)80*635a8641SAndroid Build Coastguard Worker void DeferredSequencedTaskRunner::StartWithTaskRunner(
81*635a8641SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> target_task_runner) {
82*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
83*635a8641SAndroid Build Coastguard Worker DCHECK(!target_task_runner_);
84*635a8641SAndroid Build Coastguard Worker DCHECK(target_task_runner);
85*635a8641SAndroid Build Coastguard Worker target_task_runner_ = std::move(target_task_runner);
86*635a8641SAndroid Build Coastguard Worker StartImpl();
87*635a8641SAndroid Build Coastguard Worker }
88*635a8641SAndroid Build Coastguard Worker
89*635a8641SAndroid Build Coastguard Worker DeferredSequencedTaskRunner::~DeferredSequencedTaskRunner() = default;
90*635a8641SAndroid Build Coastguard Worker
QueueDeferredTask(const Location & from_here,OnceClosure task,TimeDelta delay,bool is_non_nestable)91*635a8641SAndroid Build Coastguard Worker void DeferredSequencedTaskRunner::QueueDeferredTask(const Location& from_here,
92*635a8641SAndroid Build Coastguard Worker OnceClosure task,
93*635a8641SAndroid Build Coastguard Worker TimeDelta delay,
94*635a8641SAndroid Build Coastguard Worker bool is_non_nestable) {
95*635a8641SAndroid Build Coastguard Worker lock_.AssertAcquired();
96*635a8641SAndroid Build Coastguard Worker
97*635a8641SAndroid Build Coastguard Worker // Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167
98*635a8641SAndroid Build Coastguard Worker // for details.
99*635a8641SAndroid Build Coastguard Worker CHECK(task);
100*635a8641SAndroid Build Coastguard Worker
101*635a8641SAndroid Build Coastguard Worker DeferredTask deferred_task;
102*635a8641SAndroid Build Coastguard Worker deferred_task.posted_from = from_here;
103*635a8641SAndroid Build Coastguard Worker deferred_task.task = std::move(task);
104*635a8641SAndroid Build Coastguard Worker deferred_task.delay = delay;
105*635a8641SAndroid Build Coastguard Worker deferred_task.is_non_nestable = is_non_nestable;
106*635a8641SAndroid Build Coastguard Worker deferred_tasks_queue_.push_back(std::move(deferred_task));
107*635a8641SAndroid Build Coastguard Worker }
108*635a8641SAndroid Build Coastguard Worker
StartImpl()109*635a8641SAndroid Build Coastguard Worker void DeferredSequencedTaskRunner::StartImpl() {
110*635a8641SAndroid Build Coastguard Worker lock_.AssertAcquired(); // Callers should have grabbed the lock.
111*635a8641SAndroid Build Coastguard Worker DCHECK(!started_);
112*635a8641SAndroid Build Coastguard Worker started_ = true;
113*635a8641SAndroid Build Coastguard Worker DCHECK(target_task_runner_);
114*635a8641SAndroid Build Coastguard Worker for (std::vector<DeferredTask>::iterator i = deferred_tasks_queue_.begin();
115*635a8641SAndroid Build Coastguard Worker i != deferred_tasks_queue_.end();
116*635a8641SAndroid Build Coastguard Worker ++i) {
117*635a8641SAndroid Build Coastguard Worker DeferredTask& task = *i;
118*635a8641SAndroid Build Coastguard Worker if (task.is_non_nestable) {
119*635a8641SAndroid Build Coastguard Worker target_task_runner_->PostNonNestableDelayedTask(
120*635a8641SAndroid Build Coastguard Worker task.posted_from, std::move(task.task), task.delay);
121*635a8641SAndroid Build Coastguard Worker } else {
122*635a8641SAndroid Build Coastguard Worker target_task_runner_->PostDelayedTask(task.posted_from,
123*635a8641SAndroid Build Coastguard Worker std::move(task.task), task.delay);
124*635a8641SAndroid Build Coastguard Worker }
125*635a8641SAndroid Build Coastguard Worker }
126*635a8641SAndroid Build Coastguard Worker deferred_tasks_queue_.clear();
127*635a8641SAndroid Build Coastguard Worker }
128*635a8641SAndroid Build Coastguard Worker
129*635a8641SAndroid Build Coastguard Worker } // namespace base
130