blob: 79507f8d045f0ab5880f33274d0b9c1159fce795 [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)
Benoit Lize25859152020-07-09 11:52:0929 : created_thread_id_(PlatformThread::CurrentId()),
30 target_task_runner_(std::move(target_task_runner)) {
31#if DCHECK_IS_ON()
32 AutoLock lock(lock_);
33 DCHECK(target_task_runner_);
34#endif
Scott Violet875789e2018-02-02 07:46:4835}
[email protected]afecfb72013-04-18 17:17:3336
Scott Violet875789e2018-02-02 07:46:4837DeferredSequencedTaskRunner::DeferredSequencedTaskRunner()
38 : created_thread_id_(PlatformThread::CurrentId()) {}
[email protected]afecfb72013-04-18 17:17:3339
Brett Wilson8e88b312017-09-12 05:22:1640bool DeferredSequencedTaskRunner::PostDelayedTask(const Location& from_here,
41 OnceClosure task,
42 TimeDelta delay) {
[email protected]afecfb72013-04-18 17:17:3343 AutoLock lock(lock_);
44 if (started_) {
45 DCHECK(deferred_tasks_queue_.empty());
tzik070c8ffb2017-03-29 05:28:1246 return target_task_runner_->PostDelayedTask(from_here, std::move(task),
47 delay);
[email protected]afecfb72013-04-18 17:17:3348 }
49
tzik070c8ffb2017-03-29 05:28:1250 QueueDeferredTask(from_here, std::move(task), delay,
51 false /* is_non_nestable */);
[email protected]afecfb72013-04-18 17:17:3352 return true;
53}
54
peary23322df62017-05-09 03:55:4855bool DeferredSequencedTaskRunner::RunsTasksInCurrentSequence() const {
Scott Violet875789e2018-02-02 07:46:4856 AutoLock lock(lock_);
57 if (target_task_runner_)
58 return target_task_runner_->RunsTasksInCurrentSequence();
59
60 return created_thread_id_ == PlatformThread::CurrentId();
[email protected]afecfb72013-04-18 17:17:3361}
62
63bool DeferredSequencedTaskRunner::PostNonNestableDelayedTask(
Brett Wilson8e88b312017-09-12 05:22:1664 const Location& from_here,
tzik6e427842017-04-05 10:13:2165 OnceClosure task,
[email protected]afecfb72013-04-18 17:17:3366 TimeDelta delay) {
67 AutoLock lock(lock_);
68 if (started_) {
69 DCHECK(deferred_tasks_queue_.empty());
tzik070c8ffb2017-03-29 05:28:1270 return target_task_runner_->PostNonNestableDelayedTask(
71 from_here, std::move(task), delay);
[email protected]afecfb72013-04-18 17:17:3372 }
tzik070c8ffb2017-03-29 05:28:1273 QueueDeferredTask(from_here, std::move(task), delay,
74 true /* is_non_nestable */);
[email protected]afecfb72013-04-18 17:17:3375 return true;
76}
77
Scott Violet875789e2018-02-02 07:46:4878void DeferredSequencedTaskRunner::Start() {
79 AutoLock lock(lock_);
80 StartImpl();
81}
82
83void DeferredSequencedTaskRunner::StartWithTaskRunner(
84 scoped_refptr<SequencedTaskRunner> target_task_runner) {
85 AutoLock lock(lock_);
86 DCHECK(!target_task_runner_);
87 DCHECK(target_task_runner);
88 target_task_runner_ = std::move(target_task_runner);
89 StartImpl();
90}
91
92DeferredSequencedTaskRunner::~DeferredSequencedTaskRunner() = default;
93
Brett Wilson8e88b312017-09-12 05:22:1694void DeferredSequencedTaskRunner::QueueDeferredTask(const Location& from_here,
95 OnceClosure task,
96 TimeDelta delay,
97 bool is_non_nestable) {
Scott Violet875789e2018-02-02 07:46:4898 lock_.AssertAcquired();
99
tzik498d42b2017-04-13 07:42:48100 // Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167
101 // for details.
102 CHECK(task);
tzikc6976962017-04-04 17:27:34103
[email protected]afecfb72013-04-18 17:17:33104 DeferredTask deferred_task;
105 deferred_task.posted_from = from_here;
tzik070c8ffb2017-03-29 05:28:12106 deferred_task.task = std::move(task);
[email protected]afecfb72013-04-18 17:17:33107 deferred_task.delay = delay;
108 deferred_task.is_non_nestable = is_non_nestable;
tzik070c8ffb2017-03-29 05:28:12109 deferred_tasks_queue_.push_back(std::move(deferred_task));
[email protected]afecfb72013-04-18 17:17:33110}
111
Scott Violet875789e2018-02-02 07:46:48112void DeferredSequencedTaskRunner::StartImpl() {
113 lock_.AssertAcquired(); // Callers should have grabbed the lock.
[email protected]afecfb72013-04-18 17:17:33114 DCHECK(!started_);
115 started_ = true;
Scott Violet875789e2018-02-02 07:46:48116 DCHECK(target_task_runner_);
jdoerrie6c6229352018-10-22 15:55:43117 for (auto& task : deferred_tasks_queue_) {
[email protected]afecfb72013-04-18 17:17:33118 if (task.is_non_nestable) {
tzik070c8ffb2017-03-29 05:28:12119 target_task_runner_->PostNonNestableDelayedTask(
120 task.posted_from, std::move(task.task), task.delay);
[email protected]afecfb72013-04-18 17:17:33121 } else {
122 target_task_runner_->PostDelayedTask(task.posted_from,
tzik070c8ffb2017-03-29 05:28:12123 std::move(task.task), task.delay);
[email protected]afecfb72013-04-18 17:17:33124 }
[email protected]afecfb72013-04-18 17:17:33125 }
126 deferred_tasks_queue_.clear();
127}
128
129} // namespace base