xref: /aosp_15_r20/external/libchrome/base/deferred_sequenced_task_runner.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
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