Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(376)

Side by Side Diff: base/task_scheduler/scheduler_worker.cc

Issue 2208493002: TaskScheduler: No BACKGROUND threads when unsupported. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase + CR robliao #6 (nit) Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/task_scheduler/scheduler_worker.h" 5 #include "base/task_scheduler/scheduler_worker.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 WaitForWork(); 42 WaitForWork();
43 43
44 while (!outer_->task_tracker_->IsShutdownComplete() && 44 while (!outer_->task_tracker_->IsShutdownComplete() &&
45 !outer_->ShouldExitForTesting()) { 45 !outer_->ShouldExitForTesting()) {
46 DCHECK(outer_); 46 DCHECK(outer_);
47 47
48 #if defined(OS_MACOSX) 48 #if defined(OS_MACOSX)
49 mac::ScopedNSAutoreleasePool autorelease_pool; 49 mac::ScopedNSAutoreleasePool autorelease_pool;
50 #endif 50 #endif
51 51
52 #if !defined(OS_LINUX)
53 UpdateThreadPriority(GetDesiredThreadPriority()); 52 UpdateThreadPriority(GetDesiredThreadPriority());
54 #endif
55 53
56 // Get the sequence containing the next task to execute. 54 // Get the sequence containing the next task to execute.
57 scoped_refptr<Sequence> sequence = outer_->delegate_->GetWork(outer_); 55 scoped_refptr<Sequence> sequence = outer_->delegate_->GetWork(outer_);
58 if (!sequence) { 56 if (!sequence) {
59 if (outer_->delegate_->CanDetach(outer_)) { 57 if (outer_->delegate_->CanDetach(outer_)) {
60 detached_thread = outer_->Detach(); 58 detached_thread = outer_->Detach();
61 if (detached_thread) { 59 if (detached_thread) {
62 DCHECK_EQ(detached_thread.get(), this); 60 DCHECK_EQ(detached_thread.get(), this);
63 PlatformThread::Detach(thread_handle_); 61 PlatformThread::Detach(thread_handle_);
64 outer_ = nullptr; 62 outer_ = nullptr;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 if (sleep_time.is_max()) { 122 if (sleep_time.is_max()) {
125 // Calling TimedWait with TimeDelta::Max is not recommended per 123 // Calling TimedWait with TimeDelta::Max is not recommended per
126 // http://crbug.com/465948. 124 // http://crbug.com/465948.
127 wake_up_event_.Wait(); 125 wake_up_event_.Wait();
128 } else { 126 } else {
129 wake_up_event_.TimedWait(sleep_time); 127 wake_up_event_.TimedWait(sleep_time);
130 } 128 }
131 wake_up_event_.Reset(); 129 wake_up_event_.Reset();
132 } 130 }
133 131
134 // Returns the desired thread priority based on the worker priority and the 132 // Returns the priority for which the thread should be set based on the
135 // current shutdown state. 133 // priority hint, current shutdown state, and platform capabilities.
136 ThreadPriority GetDesiredThreadPriority() { 134 ThreadPriority GetDesiredThreadPriority() {
137 DCHECK(outer_); 135 DCHECK(outer_);
138 136
139 if (outer_->task_tracker_->HasShutdownStarted() && 137 // All threads have a NORMAL priority when Lock doesn't handle multiple
140 static_cast<int>(outer_->thread_priority_) < 138 // thread priorities.
141 static_cast<int>(ThreadPriority::NORMAL)) { 139 if (!Lock::HandlesMultipleThreadPriorities())
140 return ThreadPriority::NORMAL;
141
142 // To avoid shutdown hangs, disallow a priority below NORMAL during
143 // shutdown. If thread priority cannot be increased, never allow a priority
144 // below NORMAL.
145 if (static_cast<int>(outer_->priority_hint_) <
146 static_cast<int>(ThreadPriority::NORMAL) &&
147 (outer_->task_tracker_->HasShutdownStarted() ||
148 !PlatformThread::CanIncreaseCurrentThreadPriority())) {
142 return ThreadPriority::NORMAL; 149 return ThreadPriority::NORMAL;
143 } 150 }
144 return outer_->thread_priority_; 151
152 return outer_->priority_hint_;
145 } 153 }
146 154
147 // Increasing the thread priority requires the CAP_SYS_NICE capability on
148 // Linux.
149 #if !defined(OS_LINUX)
150 void UpdateThreadPriority(ThreadPriority desired_thread_priority) { 155 void UpdateThreadPriority(ThreadPriority desired_thread_priority) {
151 if (desired_thread_priority == current_thread_priority_) 156 if (desired_thread_priority == current_thread_priority_)
152 return; 157 return;
153 158
154 PlatformThread::SetCurrentThreadPriority(desired_thread_priority); 159 PlatformThread::SetCurrentThreadPriority(desired_thread_priority);
155 current_thread_priority_ = desired_thread_priority; 160 current_thread_priority_ = desired_thread_priority;
156 } 161 }
157 #endif // !defined(OS_LINUX)
158 162
159 PlatformThreadHandle thread_handle_; 163 PlatformThreadHandle thread_handle_;
160 164
161 SchedulerWorker* outer_; 165 SchedulerWorker* outer_;
162 166
163 // Event signaled to wake up this thread. 167 // Event signaled to wake up this thread.
164 WaitableEvent wake_up_event_; 168 WaitableEvent wake_up_event_;
165 169
166 // Current priority of this thread. May be different from 170 // Current priority of this thread. May be different from
167 // |outer_->thread_priority_| during shutdown. 171 // |outer_->priority_hint_|.
168 ThreadPriority current_thread_priority_; 172 ThreadPriority current_thread_priority_;
169 173
170 DISALLOW_COPY_AND_ASSIGN(Thread); 174 DISALLOW_COPY_AND_ASSIGN(Thread);
171 }; 175 };
172 176
173 std::unique_ptr<SchedulerWorker> SchedulerWorker::Create( 177 std::unique_ptr<SchedulerWorker> SchedulerWorker::Create(
174 ThreadPriority thread_priority, 178 ThreadPriority priority_hint,
175 std::unique_ptr<Delegate> delegate, 179 std::unique_ptr<Delegate> delegate,
176 TaskTracker* task_tracker, 180 TaskTracker* task_tracker,
177 InitialState initial_state) { 181 InitialState initial_state) {
178 std::unique_ptr<SchedulerWorker> worker( 182 std::unique_ptr<SchedulerWorker> worker(
179 new SchedulerWorker(thread_priority, std::move(delegate), task_tracker)); 183 new SchedulerWorker(priority_hint, std::move(delegate), task_tracker));
180 // Creation happens before any other thread can reference this one, so no 184 // Creation happens before any other thread can reference this one, so no
181 // synchronization is necessary. 185 // synchronization is necessary.
182 if (initial_state == SchedulerWorker::InitialState::ALIVE) { 186 if (initial_state == SchedulerWorker::InitialState::ALIVE) {
183 worker->CreateThread(); 187 worker->CreateThread();
184 if (!worker->thread_) { 188 if (!worker->thread_) {
185 return nullptr; 189 return nullptr;
186 } 190 }
187 } 191 }
188 192
189 return worker; 193 return worker;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 thread_->Join(); 225 thread_->Join();
222 226
223 thread_.reset(); 227 thread_.reset();
224 } 228 }
225 229
226 bool SchedulerWorker::ThreadAliveForTesting() const { 230 bool SchedulerWorker::ThreadAliveForTesting() const {
227 AutoSchedulerLock auto_lock(thread_lock_); 231 AutoSchedulerLock auto_lock(thread_lock_);
228 return !!thread_; 232 return !!thread_;
229 } 233 }
230 234
231 SchedulerWorker::SchedulerWorker(ThreadPriority thread_priority, 235 SchedulerWorker::SchedulerWorker(ThreadPriority priority_hint,
232 std::unique_ptr<Delegate> delegate, 236 std::unique_ptr<Delegate> delegate,
233 TaskTracker* task_tracker) 237 TaskTracker* task_tracker)
234 : thread_priority_(thread_priority), 238 : priority_hint_(priority_hint),
235 delegate_(std::move(delegate)), 239 delegate_(std::move(delegate)),
236 task_tracker_(task_tracker) { 240 task_tracker_(task_tracker) {
237 DCHECK(delegate_); 241 DCHECK(delegate_);
238 DCHECK(task_tracker_); 242 DCHECK(task_tracker_);
239 } 243 }
240 244
241 std::unique_ptr<SchedulerWorker::Thread> SchedulerWorker::Detach() { 245 std::unique_ptr<SchedulerWorker::Thread> SchedulerWorker::Detach() {
242 DCHECK(!ShouldExitForTesting()) << "Worker was already joined"; 246 DCHECK(!ShouldExitForTesting()) << "Worker was already joined";
243 AutoSchedulerLock auto_lock(thread_lock_); 247 AutoSchedulerLock auto_lock(thread_lock_);
244 // If a wakeup is pending, then a WakeUp() came in while we were deciding to 248 // If a wakeup is pending, then a WakeUp() came in while we were deciding to
(...skipping 11 matching lines...) Expand all
256 CreateThread(); 260 CreateThread();
257 } 261 }
258 262
259 bool SchedulerWorker::ShouldExitForTesting() const { 263 bool SchedulerWorker::ShouldExitForTesting() const {
260 AutoSchedulerLock auto_lock(should_exit_for_testing_lock_); 264 AutoSchedulerLock auto_lock(should_exit_for_testing_lock_);
261 return should_exit_for_testing_; 265 return should_exit_for_testing_;
262 } 266 }
263 267
264 } // namespace internal 268 } // namespace internal
265 } // namespace base 269 } // namespace base
OLDNEW
« no previous file with comments | « base/task_scheduler/scheduler_worker.h ('k') | base/task_scheduler/scheduler_worker_pool_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698