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

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

Issue 2806413002: Separate the create and start phases in SchedulerSingleThreadTaskRunnerManager. (Closed)
Patch Set: self-review Created 3 years, 8 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 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 if (sleep_time.is_max()) { 194 if (sleep_time.is_max()) {
195 // Calling TimedWait with TimeDelta::Max is not recommended per 195 // Calling TimedWait with TimeDelta::Max is not recommended per
196 // http://crbug.com/465948. 196 // http://crbug.com/465948.
197 wake_up_event->Wait(); 197 wake_up_event->Wait();
198 } else { 198 } else {
199 wake_up_event->TimedWait(sleep_time); 199 wake_up_event->TimedWait(sleep_time);
200 } 200 }
201 wake_up_event->Reset(); 201 wake_up_event->Reset();
202 } 202 }
203 203
204 scoped_refptr<SchedulerWorker> SchedulerWorker::Create( 204 SchedulerWorker::SchedulerWorker(
205 ThreadPriority priority_hint, 205 ThreadPriority priority_hint,
206 std::unique_ptr<Delegate> delegate, 206 std::unique_ptr<Delegate> delegate,
207 TaskTracker* task_tracker, 207 TaskTracker* task_tracker,
208 InitialState initial_state, 208 SchedulerBackwardCompatibility backward_compatibility)
209 SchedulerBackwardCompatibility backward_compatibility) { 209 : priority_hint_(priority_hint),
210 scoped_refptr<SchedulerWorker> worker( 210 delegate_(std::move(delegate)),
211 new SchedulerWorker(priority_hint, std::move(delegate), task_tracker, 211 task_tracker_(task_tracker)
212 backward_compatibility)); 212 #if defined(OS_WIN)
213 // Creation happens before any other thread can reference this one, so no 213 ,
214 // synchronization is necessary. 214 backward_compatibility_(backward_compatibility)
215 if (initial_state == SchedulerWorker::InitialState::ALIVE) { 215 #endif
216 worker->CreateThread(); 216 {
217 if (!worker->thread_) { 217 DCHECK(delegate_);
218 return nullptr; 218 DCHECK(task_tracker_);
219 } 219 }
220
221 bool SchedulerWorker::Start(InitialState initial_state) {
222 AutoSchedulerLock auto_lock(thread_lock_);
223 DCHECK(!started_);
224 DCHECK(!thread_);
225
226 if (should_exit_.IsSet() || join_called_for_testing_.IsSet())
227 return true;
228
229 started_ = true;
230
231 if (initial_state == InitialState::ALIVE) {
232 CreateThreadAssertSynchronized();
233 return !!thread_;
220 } 234 }
221 235
222 return worker; 236 return true;
223 } 237 }
224 238
225 void SchedulerWorker::WakeUp() { 239 void SchedulerWorker::WakeUp() {
226 AutoSchedulerLock auto_lock(thread_lock_); 240 AutoSchedulerLock auto_lock(thread_lock_);
227 241
228 DCHECK(!join_called_for_testing_.IsSet()); 242 DCHECK(!join_called_for_testing_.IsSet());
229 243
230 if (!thread_) 244 if (!thread_)
231 CreateThreadAssertSynchronized(); 245 CreateThreadAssertSynchronized();
232 246
(...skipping 26 matching lines...) Expand all
259 AutoSchedulerLock auto_lock(thread_lock_); 273 AutoSchedulerLock auto_lock(thread_lock_);
260 return !!thread_; 274 return !!thread_;
261 } 275 }
262 276
263 void SchedulerWorker::Cleanup() { 277 void SchedulerWorker::Cleanup() {
264 // |should_exit_| is synchronized with |thread_| for writes here so that we 278 // |should_exit_| is synchronized with |thread_| for writes here so that we
265 // can maintain access to |thread_| for wakeup. Otherwise, the thread may take 279 // can maintain access to |thread_| for wakeup. Otherwise, the thread may take
266 // away |thread_| for destruction. 280 // away |thread_| for destruction.
267 AutoSchedulerLock auto_lock(thread_lock_); 281 AutoSchedulerLock auto_lock(thread_lock_);
268 DCHECK(!should_exit_.IsSet()); 282 DCHECK(!should_exit_.IsSet());
269 if (thread_) { 283 should_exit_.Set();
270 should_exit_.Set(); 284 if (thread_)
271 thread_->WakeUp(); 285 thread_->WakeUp();
272 }
273 }
274
275 SchedulerWorker::SchedulerWorker(
276 ThreadPriority priority_hint,
277 std::unique_ptr<Delegate> delegate,
278 TaskTracker* task_tracker,
279 SchedulerBackwardCompatibility backward_compatibility)
280 : priority_hint_(priority_hint),
281 delegate_(std::move(delegate)),
282 task_tracker_(task_tracker)
283 #if defined(OS_WIN)
284 ,
285 backward_compatibility_(backward_compatibility)
286 #endif
287 {
288 DCHECK(delegate_);
289 DCHECK(task_tracker_);
290 } 286 }
291 287
292 SchedulerWorker::~SchedulerWorker() { 288 SchedulerWorker::~SchedulerWorker() {
293 // It is unexpected for |thread_| to be alive and for SchedulerWorker to 289 // It is unexpected for |thread_| to be alive and for SchedulerWorker to
294 // destroy since SchedulerWorker owns the delegate needed by |thread_|. 290 // destroy since SchedulerWorker owns the delegate needed by |thread_|.
295 // For testing, this generally means JoinForTesting was not called. 291 // For testing, this generally means JoinForTesting was not called.
296 DCHECK(!thread_); 292 DCHECK(!thread_);
297 } 293 }
298 294
299 std::unique_ptr<SchedulerWorker::Thread> SchedulerWorker::DetachThreadObject( 295 std::unique_ptr<SchedulerWorker::Thread> SchedulerWorker::DetachThreadObject(
(...skipping 14 matching lines...) Expand all
314 310
315 if (detach_notify == DetachNotify::DELEGATE) { 311 if (detach_notify == DetachNotify::DELEGATE) {
316 // Call OnDetach() within the scope of |thread_lock_| to prevent the 312 // Call OnDetach() within the scope of |thread_lock_| to prevent the
317 // delegate from being used concurrently from an old and a new thread. 313 // delegate from being used concurrently from an old and a new thread.
318 delegate_->OnDetach(); 314 delegate_->OnDetach();
319 } 315 }
320 316
321 return std::move(thread_); 317 return std::move(thread_);
322 } 318 }
323 319
324 void SchedulerWorker::CreateThread() { 320 void SchedulerWorker::CreateThread() {
gab 2017/04/10 18:04:56 Last caller of this is now CreateThreadAssertSynch
fdoray 2017/04/10 19:05:00 Done.
325 thread_ = Thread::Create(make_scoped_refptr(this)); 321 if (started_)
322 thread_ = Thread::Create(make_scoped_refptr(this));
326 } 323 }
327 324
328 void SchedulerWorker::CreateThreadAssertSynchronized() { 325 void SchedulerWorker::CreateThreadAssertSynchronized() {
329 thread_lock_.AssertAcquired(); 326 thread_lock_.AssertAcquired();
330 CreateThread(); 327 CreateThread();
331 } 328 }
332 329
333 bool SchedulerWorker::ShouldExit() { 330 bool SchedulerWorker::ShouldExit() {
334 // The ordering of the checks is important below. This SchedulerWorker may be 331 // The ordering of the checks is important below. This SchedulerWorker may be
335 // released and outlive |task_tracker_| in unit tests. However, when the 332 // released and outlive |task_tracker_| in unit tests. However, when the
336 // SchedulerWorker is released, |should_exit_| will be set, so check that 333 // SchedulerWorker is released, |should_exit_| will be set, so check that
337 // first. 334 // first.
338 return should_exit_.IsSet() || join_called_for_testing_.IsSet() || 335 return should_exit_.IsSet() || join_called_for_testing_.IsSet() ||
339 task_tracker_->IsShutdownComplete(); 336 task_tracker_->IsShutdownComplete();
340 } 337 }
341 338
342 } // namespace internal 339 } // namespace internal
343 } // namespace base 340 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698