blob: 0495b12a353ef7f8f37265e8b92156c2e8d0efb8 [file] [log] [blame]
[email protected]afecfb72013-04-18 17:17:331// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/deferred_sequenced_task_runner.h"
6
tzik070c8ffb2017-03-29 05:28:127#include <utility>
8
[email protected]afecfb72013-04-18 17:17:339#include "base/bind.h"
Hans Wennborgc3cffa62020-04-27 10:09:1210#include "base/check.h"
[email protected]afecfb72013-04-18 17:17:3311
12namespace base {
13
[email protected]20ad4c202013-08-30 12:59:2514DeferredSequencedTaskRunner::DeferredTask::DeferredTask()
15 : is_non_nestable(false) {
[email protected]afecfb72013-04-18 17:17:3316}
17
tzik070c8ffb2017-03-29 05:28:1218DeferredSequencedTaskRunner::DeferredTask::DeferredTask(DeferredTask&& other) =
19 default;
vmpstr7c7877062016-02-18 22:12:2420
Chris Watkinsbb7211c2017-11-29 07:16:3821DeferredSequencedTaskRunner::DeferredTask::~DeferredTask() = default;
[email protected]afecfb72013-04-18 17:17:3322
tzik070c8ffb2017-03-29 05:28:1223DeferredSequencedTaskRunner::DeferredTask&
24DeferredSequencedTaskRunner::DeferredTask::operator=(DeferredTask&& other) =
25 default;
26
[email protected]afecfb72013-04-18 17:17:3327DeferredSequencedTaskRunner::DeferredSequencedTaskRunner(
vmpstr82b0c16d2016-03-18 19:17:2828 scoped_refptr<SequencedTaskRunner> target_task_runner)
Scott Violet875789e2018-02-02 07:46:4829 : DeferredSequencedTaskRunner() {
30 DCHECK(target_task_runner);
31 target_task_runner_ = std::move(target_task_runner);
32}
[email protected]afecfb72013-04-18 17:17:3333
Scott Violet875789e2018-02-02 07:46:4834DeferredSequencedTaskRunner::DeferredSequencedTaskRunner()
35 : created_thread_id_(PlatformThread::CurrentId()) {}
[email protected]afecfb72013-04-18 17:17:3336
Brett Wilson8e88b312017-09-12 05:22:1637bool DeferredSequencedTaskRunner::PostDelayedTask(const Location& from_here,
38 OnceClosure task,
39 TimeDelta delay) {
[email protected]afecfb72013-04-18 17:17:3340 AutoLock lock(lock_);
41 if (started_) {
42 DCHECK(deferred_tasks_queue_.empty());
tzik070c8ffb2017-03-29 05:28:1243 return target_task_runner_->PostDelayedTask(from_here, std::move(task),
44 delay);
[email protected]afecfb72013-04-18 17:17:3345 }
46
tzik070c8ffb2017-03-29 05:28:1247 QueueDeferredTask(from_here, std::move(task), delay,
48 false /* is_non_nestable */);
[email protected]afecfb72013-04-18 17:17:3349 return true;
50}
51
peary23322df62017-05-09 03:55:4852bool DeferredSequencedTaskRunner::RunsTasksInCurrentSequence() const {
Scott Violet875789e2018-02-02 07:46:4853 AutoLock lock(lock_);
54 if (target_task_runner_)
55 return target_task_runner_->RunsTasksInCurrentSequence();
56
57 return created_thread_id_ == PlatformThread::CurrentId();
[email protected]afecfb72013-04-18 17:17:3358}
59
60bool DeferredSequencedTaskRunner::PostNonNestableDelayedTask(
Brett Wilson8e88b312017-09-12 05:22:1661 const Location& from_here,
tzik6e427842017-04-05 10:13:2162 OnceClosure task,
[email protected]afecfb72013-04-18 17:17:3363 TimeDelta delay) {
64 AutoLock lock(lock_);
65 if (started_) {
66 DCHECK(deferred_tasks_queue_.empty());
tzik070c8ffb2017-03-29 05:28:1267 return target_task_runner_->PostNonNestableDelayedTask(
68 from_here, std::move(task), delay);
[email protected]afecfb72013-04-18 17:17:3369 }
tzik070c8ffb2017-03-29 05:28:1270 QueueDeferredTask(from_here, std::move(task), delay,
71 true /* is_non_nestable */);
[email protected]afecfb72013-04-18 17:17:3372 return true;
73}
74
Scott Violet875789e2018-02-02 07:46:4875void DeferredSequencedTaskRunner::Start() {
76 AutoLock lock(lock_);
77 StartImpl();
78}
79
80void DeferredSequencedTaskRunner::StartWithTaskRunner(
81 scoped_refptr<SequencedTaskRunner> target_task_runner) {
82 AutoLock lock(lock_);
83 DCHECK(!target_task_runner_);
84 DCHECK(target_task_runner);
85 target_task_runner_ = std::move(target_task_runner);
86 StartImpl();
87}
88
89DeferredSequencedTaskRunner::~DeferredSequencedTaskRunner() = default;
90
Brett Wilson8e88b312017-09-12 05:22:1691void DeferredSequencedTaskRunner::QueueDeferredTask(const Location& from_here,
92 OnceClosure task,
93 TimeDelta delay,
94 bool is_non_nestable) {
Scott Violet875789e2018-02-02 07:46:4895 lock_.AssertAcquired();
96
tzik498d42b2017-04-13 07:42:4897 // Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167
98 // for details.
99 CHECK(task);
tzikc6976962017-04-04 17:27:34100
[email protected]afecfb72013-04-18 17:17:33101 DeferredTask deferred_task;
102 deferred_task.posted_from = from_here;
tzik070c8ffb2017-03-29 05:28:12103 deferred_task.task = std::move(task);
[email protected]afecfb72013-04-18 17:17:33104 deferred_task.delay = delay;
105 deferred_task.is_non_nestable = is_non_nestable;
tzik070c8ffb2017-03-29 05:28:12106 deferred_tasks_queue_.push_back(std::move(deferred_task));
[email protected]afecfb72013-04-18 17:17:33107}
108
Scott Violet875789e2018-02-02 07:46:48109void DeferredSequencedTaskRunner::StartImpl() {
110 lock_.AssertAcquired(); // Callers should have grabbed the lock.
[email protected]afecfb72013-04-18 17:17:33111 DCHECK(!started_);
112 started_ = true;
Scott Violet875789e2018-02-02 07:46:48113 DCHECK(target_task_runner_);
jdoerrie6c6229352018-10-22 15:55:43114 for (auto& task : deferred_tasks_queue_) {
[email protected]afecfb72013-04-18 17:17:33115 if (task.is_non_nestable) {
tzik070c8ffb2017-03-29 05:28:12116 target_task_runner_->PostNonNestableDelayedTask(
117 task.posted_from, std::move(task.task), task.delay);
[email protected]afecfb72013-04-18 17:17:33118 } else {
119 target_task_runner_->PostDelayedTask(task.posted_from,
tzik070c8ffb2017-03-29 05:28:12120 std::move(task.task), task.delay);
[email protected]afecfb72013-04-18 17:17:33121 }
[email protected]afecfb72013-04-18 17:17:33122 }
123 deferred_tasks_queue_.clear();
124}
125
126} // namespace base