1 // Copyright 2016 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/task_scheduler/post_task.h"
6
7 #include <utility>
8
9 #include "base/logging.h"
10 #include "base/task_scheduler/scoped_set_task_priority_for_current_thread.h"
11 #include "base/task_scheduler/task_scheduler.h"
12 #include "base/threading/post_task_and_reply_impl.h"
13
14 namespace base {
15
16 namespace {
17
18 class PostTaskAndReplyWithTraitsTaskRunner
19 : public internal::PostTaskAndReplyImpl {
20 public:
PostTaskAndReplyWithTraitsTaskRunner(const TaskTraits & traits)21 explicit PostTaskAndReplyWithTraitsTaskRunner(const TaskTraits& traits)
22 : traits_(traits) {}
23
24 private:
PostTask(const Location & from_here,OnceClosure task)25 bool PostTask(const Location& from_here, OnceClosure task) override {
26 PostTaskWithTraits(from_here, traits_, std::move(task));
27 return true;
28 }
29
30 const TaskTraits traits_;
31 };
32
33 // Returns TaskTraits based on |traits|. If TaskPriority hasn't been set
34 // explicitly in |traits|, the returned TaskTraits have the current
35 // TaskPriority.
GetTaskTraitsWithExplicitPriority(const TaskTraits & traits)36 TaskTraits GetTaskTraitsWithExplicitPriority(const TaskTraits& traits) {
37 if (traits.priority_set_explicitly())
38 return traits;
39 return TaskTraits::Override(traits,
40 {internal::GetTaskPriorityForCurrentThread()});
41 }
42
43 } // namespace
44
PostTask(const Location & from_here,OnceClosure task)45 void PostTask(const Location& from_here, OnceClosure task) {
46 PostDelayedTask(from_here, std::move(task), TimeDelta());
47 }
48
PostDelayedTask(const Location & from_here,OnceClosure task,TimeDelta delay)49 void PostDelayedTask(const Location& from_here,
50 OnceClosure task,
51 TimeDelta delay) {
52 PostDelayedTaskWithTraits(from_here, TaskTraits(), std::move(task), delay);
53 }
54
PostTaskAndReply(const Location & from_here,OnceClosure task,OnceClosure reply)55 void PostTaskAndReply(const Location& from_here,
56 OnceClosure task,
57 OnceClosure reply) {
58 PostTaskWithTraitsAndReply(from_here, TaskTraits(), std::move(task),
59 std::move(reply));
60 }
61
PostTaskWithTraits(const Location & from_here,const TaskTraits & traits,OnceClosure task)62 void PostTaskWithTraits(const Location& from_here,
63 const TaskTraits& traits,
64 OnceClosure task) {
65 PostDelayedTaskWithTraits(from_here, traits, std::move(task), TimeDelta());
66 }
67
PostDelayedTaskWithTraits(const Location & from_here,const TaskTraits & traits,OnceClosure task,TimeDelta delay)68 void PostDelayedTaskWithTraits(const Location& from_here,
69 const TaskTraits& traits,
70 OnceClosure task,
71 TimeDelta delay) {
72 DCHECK(TaskScheduler::GetInstance())
73 << "Ref. Prerequisite section of post_task.h.\n\n"
74 "Hint: if this is in a unit test, you're likely merely missing a "
75 "base::test::ScopedTaskEnvironment member in your fixture.\n";
76 TaskScheduler::GetInstance()->PostDelayedTaskWithTraits(
77 from_here, GetTaskTraitsWithExplicitPriority(traits), std::move(task),
78 std::move(delay));
79 }
80
PostTaskWithTraitsAndReply(const Location & from_here,const TaskTraits & traits,OnceClosure task,OnceClosure reply)81 void PostTaskWithTraitsAndReply(const Location& from_here,
82 const TaskTraits& traits,
83 OnceClosure task,
84 OnceClosure reply) {
85 PostTaskAndReplyWithTraitsTaskRunner(traits).PostTaskAndReply(
86 from_here, std::move(task), std::move(reply));
87 }
88
CreateTaskRunnerWithTraits(const TaskTraits & traits)89 scoped_refptr<TaskRunner> CreateTaskRunnerWithTraits(const TaskTraits& traits) {
90 DCHECK(TaskScheduler::GetInstance())
91 << "Ref. Prerequisite section of post_task.h.\n\n"
92 "Hint: if this is in a unit test, you're likely merely missing a "
93 "base::test::ScopedTaskEnvironment member in your fixture.\n";
94 return TaskScheduler::GetInstance()->CreateTaskRunnerWithTraits(
95 GetTaskTraitsWithExplicitPriority(traits));
96 }
97
CreateSequencedTaskRunnerWithTraits(const TaskTraits & traits)98 scoped_refptr<SequencedTaskRunner> CreateSequencedTaskRunnerWithTraits(
99 const TaskTraits& traits) {
100 DCHECK(TaskScheduler::GetInstance())
101 << "Ref. Prerequisite section of post_task.h.\n\n"
102 "Hint: if this is in a unit test, you're likely merely missing a "
103 "base::test::ScopedTaskEnvironment member in your fixture.\n";
104 return TaskScheduler::GetInstance()->CreateSequencedTaskRunnerWithTraits(
105 GetTaskTraitsWithExplicitPriority(traits));
106 }
107
CreateSingleThreadTaskRunnerWithTraits(const TaskTraits & traits,SingleThreadTaskRunnerThreadMode thread_mode)108 scoped_refptr<SingleThreadTaskRunner> CreateSingleThreadTaskRunnerWithTraits(
109 const TaskTraits& traits,
110 SingleThreadTaskRunnerThreadMode thread_mode) {
111 DCHECK(TaskScheduler::GetInstance())
112 << "Ref. Prerequisite section of post_task.h.\n\n"
113 "Hint: if this is in a unit test, you're likely merely missing a "
114 "base::test::ScopedTaskEnvironment member in your fixture.\n";
115 return TaskScheduler::GetInstance()->CreateSingleThreadTaskRunnerWithTraits(
116 GetTaskTraitsWithExplicitPriority(traits), thread_mode);
117 }
118
119 #if defined(OS_WIN)
CreateCOMSTATaskRunnerWithTraits(const TaskTraits & traits,SingleThreadTaskRunnerThreadMode thread_mode)120 scoped_refptr<SingleThreadTaskRunner> CreateCOMSTATaskRunnerWithTraits(
121 const TaskTraits& traits,
122 SingleThreadTaskRunnerThreadMode thread_mode) {
123 DCHECK(TaskScheduler::GetInstance())
124 << "Ref. Prerequisite section of post_task.h.\n\n"
125 "Hint: if this is in a unit test, you're likely merely missing a "
126 "base::test::ScopedTaskEnvironment member in your fixture.\n";
127 return TaskScheduler::GetInstance()->CreateCOMSTATaskRunnerWithTraits(
128 GetTaskTraitsWithExplicitPriority(traits), thread_mode);
129 }
130 #endif // defined(OS_WIN)
131
132 } // namespace base
133