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