1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/task/sequenced_task_runner.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <utility>
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/task/default_delayed_task_handle_delegate.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
12*6777b538SAndroid Build Coastguard Worker #include "third_party/abseil-cpp/absl/base/attributes.h"
13*6777b538SAndroid Build Coastguard Worker
14*6777b538SAndroid Build Coastguard Worker namespace base {
15*6777b538SAndroid Build Coastguard Worker
16*6777b538SAndroid Build Coastguard Worker namespace {
17*6777b538SAndroid Build Coastguard Worker
18*6777b538SAndroid Build Coastguard Worker ABSL_CONST_INIT thread_local SequencedTaskRunner::CurrentDefaultHandle*
19*6777b538SAndroid Build Coastguard Worker current_default_handle = nullptr;
20*6777b538SAndroid Build Coastguard Worker
21*6777b538SAndroid Build Coastguard Worker } // namespace
22*6777b538SAndroid Build Coastguard Worker
PostNonNestableTask(const Location & from_here,OnceClosure task)23*6777b538SAndroid Build Coastguard Worker bool SequencedTaskRunner::PostNonNestableTask(const Location& from_here,
24*6777b538SAndroid Build Coastguard Worker OnceClosure task) {
25*6777b538SAndroid Build Coastguard Worker return PostNonNestableDelayedTask(from_here, std::move(task),
26*6777b538SAndroid Build Coastguard Worker base::TimeDelta());
27*6777b538SAndroid Build Coastguard Worker }
28*6777b538SAndroid Build Coastguard Worker
PostCancelableDelayedTask(subtle::PostDelayedTaskPassKey,const Location & from_here,OnceClosure task,TimeDelta delay)29*6777b538SAndroid Build Coastguard Worker DelayedTaskHandle SequencedTaskRunner::PostCancelableDelayedTask(
30*6777b538SAndroid Build Coastguard Worker subtle::PostDelayedTaskPassKey,
31*6777b538SAndroid Build Coastguard Worker const Location& from_here,
32*6777b538SAndroid Build Coastguard Worker OnceClosure task,
33*6777b538SAndroid Build Coastguard Worker TimeDelta delay) {
34*6777b538SAndroid Build Coastguard Worker auto delayed_task_handle_delegate =
35*6777b538SAndroid Build Coastguard Worker std::make_unique<DefaultDelayedTaskHandleDelegate>();
36*6777b538SAndroid Build Coastguard Worker
37*6777b538SAndroid Build Coastguard Worker task = delayed_task_handle_delegate->BindCallback(std::move(task));
38*6777b538SAndroid Build Coastguard Worker
39*6777b538SAndroid Build Coastguard Worker DelayedTaskHandle delayed_task_handle(
40*6777b538SAndroid Build Coastguard Worker std::move(delayed_task_handle_delegate));
41*6777b538SAndroid Build Coastguard Worker
42*6777b538SAndroid Build Coastguard Worker PostDelayedTask(from_here, std::move(task), delay);
43*6777b538SAndroid Build Coastguard Worker
44*6777b538SAndroid Build Coastguard Worker return delayed_task_handle;
45*6777b538SAndroid Build Coastguard Worker }
46*6777b538SAndroid Build Coastguard Worker
PostCancelableDelayedTaskAt(subtle::PostDelayedTaskPassKey pass_key,const Location & from_here,OnceClosure task,TimeTicks delayed_run_time,subtle::DelayPolicy deadline_policy)47*6777b538SAndroid Build Coastguard Worker DelayedTaskHandle SequencedTaskRunner::PostCancelableDelayedTaskAt(
48*6777b538SAndroid Build Coastguard Worker subtle::PostDelayedTaskPassKey pass_key,
49*6777b538SAndroid Build Coastguard Worker const Location& from_here,
50*6777b538SAndroid Build Coastguard Worker OnceClosure task,
51*6777b538SAndroid Build Coastguard Worker TimeTicks delayed_run_time,
52*6777b538SAndroid Build Coastguard Worker subtle::DelayPolicy deadline_policy) {
53*6777b538SAndroid Build Coastguard Worker auto delayed_task_handle_delegate =
54*6777b538SAndroid Build Coastguard Worker std::make_unique<DefaultDelayedTaskHandleDelegate>();
55*6777b538SAndroid Build Coastguard Worker
56*6777b538SAndroid Build Coastguard Worker task = delayed_task_handle_delegate->BindCallback(std::move(task));
57*6777b538SAndroid Build Coastguard Worker
58*6777b538SAndroid Build Coastguard Worker DelayedTaskHandle delayed_task_handle(
59*6777b538SAndroid Build Coastguard Worker std::move(delayed_task_handle_delegate));
60*6777b538SAndroid Build Coastguard Worker
61*6777b538SAndroid Build Coastguard Worker if (!PostDelayedTaskAt(pass_key, from_here, std::move(task), delayed_run_time,
62*6777b538SAndroid Build Coastguard Worker deadline_policy)) {
63*6777b538SAndroid Build Coastguard Worker DCHECK(!delayed_task_handle.IsValid());
64*6777b538SAndroid Build Coastguard Worker }
65*6777b538SAndroid Build Coastguard Worker return delayed_task_handle;
66*6777b538SAndroid Build Coastguard Worker }
67*6777b538SAndroid Build Coastguard Worker
PostDelayedTaskAt(subtle::PostDelayedTaskPassKey,const Location & from_here,OnceClosure task,TimeTicks delayed_run_time,subtle::DelayPolicy deadline_policy)68*6777b538SAndroid Build Coastguard Worker bool SequencedTaskRunner::PostDelayedTaskAt(
69*6777b538SAndroid Build Coastguard Worker subtle::PostDelayedTaskPassKey,
70*6777b538SAndroid Build Coastguard Worker const Location& from_here,
71*6777b538SAndroid Build Coastguard Worker OnceClosure task,
72*6777b538SAndroid Build Coastguard Worker TimeTicks delayed_run_time,
73*6777b538SAndroid Build Coastguard Worker subtle::DelayPolicy deadline_policy) {
74*6777b538SAndroid Build Coastguard Worker return PostDelayedTask(from_here, std::move(task),
75*6777b538SAndroid Build Coastguard Worker delayed_run_time.is_null()
76*6777b538SAndroid Build Coastguard Worker ? base::TimeDelta()
77*6777b538SAndroid Build Coastguard Worker : delayed_run_time - TimeTicks::Now());
78*6777b538SAndroid Build Coastguard Worker }
79*6777b538SAndroid Build Coastguard Worker
RunOrPostTask(subtle::RunOrPostTaskPassKey,const Location & from_here,OnceClosure task)80*6777b538SAndroid Build Coastguard Worker bool SequencedTaskRunner::RunOrPostTask(subtle::RunOrPostTaskPassKey,
81*6777b538SAndroid Build Coastguard Worker const Location& from_here,
82*6777b538SAndroid Build Coastguard Worker OnceClosure task) {
83*6777b538SAndroid Build Coastguard Worker return PostTask(from_here, std::move(task));
84*6777b538SAndroid Build Coastguard Worker }
85*6777b538SAndroid Build Coastguard Worker
86*6777b538SAndroid Build Coastguard Worker // static
87*6777b538SAndroid Build Coastguard Worker const scoped_refptr<SequencedTaskRunner>&
GetCurrentDefault()88*6777b538SAndroid Build Coastguard Worker SequencedTaskRunner::GetCurrentDefault() {
89*6777b538SAndroid Build Coastguard Worker CHECK(HasCurrentDefault())
90*6777b538SAndroid Build Coastguard Worker << "Error: This caller requires a sequenced context (i.e. the current "
91*6777b538SAndroid Build Coastguard Worker "task needs to run from a SequencedTaskRunner). If you're in a test "
92*6777b538SAndroid Build Coastguard Worker "refer to //docs/threading_and_tasks_testing.md.";
93*6777b538SAndroid Build Coastguard Worker return current_default_handle->task_runner_;
94*6777b538SAndroid Build Coastguard Worker }
95*6777b538SAndroid Build Coastguard Worker
96*6777b538SAndroid Build Coastguard Worker // static
HasCurrentDefault()97*6777b538SAndroid Build Coastguard Worker bool SequencedTaskRunner::HasCurrentDefault() {
98*6777b538SAndroid Build Coastguard Worker return !!current_default_handle && !!current_default_handle->task_runner_;
99*6777b538SAndroid Build Coastguard Worker }
100*6777b538SAndroid Build Coastguard Worker
CurrentDefaultHandle(scoped_refptr<SequencedTaskRunner> task_runner)101*6777b538SAndroid Build Coastguard Worker SequencedTaskRunner::CurrentDefaultHandle::CurrentDefaultHandle(
102*6777b538SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> task_runner)
103*6777b538SAndroid Build Coastguard Worker : CurrentDefaultHandle(std::move(task_runner), MayAlreadyExist{}) {
104*6777b538SAndroid Build Coastguard Worker CHECK(!previous_handle_ || !previous_handle_->task_runner_);
105*6777b538SAndroid Build Coastguard Worker }
106*6777b538SAndroid Build Coastguard Worker
~CurrentDefaultHandle()107*6777b538SAndroid Build Coastguard Worker SequencedTaskRunner::CurrentDefaultHandle::~CurrentDefaultHandle() {
108*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(current_default_handle, this);
109*6777b538SAndroid Build Coastguard Worker current_default_handle = previous_handle_;
110*6777b538SAndroid Build Coastguard Worker }
111*6777b538SAndroid Build Coastguard Worker
CurrentDefaultHandle(scoped_refptr<SequencedTaskRunner> task_runner,MayAlreadyExist)112*6777b538SAndroid Build Coastguard Worker SequencedTaskRunner::CurrentDefaultHandle::CurrentDefaultHandle(
113*6777b538SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> task_runner,
114*6777b538SAndroid Build Coastguard Worker MayAlreadyExist)
115*6777b538SAndroid Build Coastguard Worker : task_runner_(std::move(task_runner)),
116*6777b538SAndroid Build Coastguard Worker previous_handle_(current_default_handle) {
117*6777b538SAndroid Build Coastguard Worker // Support overriding the current default with a null task runner or a task
118*6777b538SAndroid Build Coastguard Worker // runner that runs its tasks in the current sequence.
119*6777b538SAndroid Build Coastguard Worker DCHECK(!task_runner_ || task_runner_->RunsTasksInCurrentSequence());
120*6777b538SAndroid Build Coastguard Worker current_default_handle = this;
121*6777b538SAndroid Build Coastguard Worker }
122*6777b538SAndroid Build Coastguard Worker
DeleteOrReleaseSoonInternal(const Location & from_here,void (* deleter)(const void *),const void * object)123*6777b538SAndroid Build Coastguard Worker bool SequencedTaskRunner::DeleteOrReleaseSoonInternal(
124*6777b538SAndroid Build Coastguard Worker const Location& from_here,
125*6777b538SAndroid Build Coastguard Worker void (*deleter)(const void*),
126*6777b538SAndroid Build Coastguard Worker const void* object) {
127*6777b538SAndroid Build Coastguard Worker return PostNonNestableTask(from_here, BindOnce(deleter, object));
128*6777b538SAndroid Build Coastguard Worker }
129*6777b538SAndroid Build Coastguard Worker
OnTaskRunnerDeleter(scoped_refptr<SequencedTaskRunner> task_runner)130*6777b538SAndroid Build Coastguard Worker OnTaskRunnerDeleter::OnTaskRunnerDeleter(
131*6777b538SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> task_runner)
132*6777b538SAndroid Build Coastguard Worker : task_runner_(std::move(task_runner)) {
133*6777b538SAndroid Build Coastguard Worker }
134*6777b538SAndroid Build Coastguard Worker
135*6777b538SAndroid Build Coastguard Worker OnTaskRunnerDeleter::~OnTaskRunnerDeleter() = default;
136*6777b538SAndroid Build Coastguard Worker
137*6777b538SAndroid Build Coastguard Worker OnTaskRunnerDeleter::OnTaskRunnerDeleter(OnTaskRunnerDeleter&&) = default;
138*6777b538SAndroid Build Coastguard Worker
139*6777b538SAndroid Build Coastguard Worker OnTaskRunnerDeleter& OnTaskRunnerDeleter::operator=(
140*6777b538SAndroid Build Coastguard Worker OnTaskRunnerDeleter&&) = default;
141*6777b538SAndroid Build Coastguard Worker
142*6777b538SAndroid Build Coastguard Worker } // namespace base
143