OLD | NEW |
---|---|
(Empty) | |
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/scheduler_worker_thread.h" | |
6 | |
7 #include <stddef.h> | |
8 | |
9 #include <utility> | |
10 | |
11 #include "base/logging.h" | |
12 #include "base/task_scheduler/task_tracker.h" | |
13 | |
14 namespace base { | |
15 namespace internal { | |
16 | |
17 scoped_ptr<SchedulerWorkerThread> | |
18 SchedulerWorkerThread::CreateSchedulerWorkerThread( | |
19 ThreadPriority thread_priority, | |
20 const Closure& main_entry_callback, | |
21 const GetWorkCallback& get_work_callback, | |
22 const RanTaskFromSequenceCallback& ran_task_from_sequence_callback, | |
23 TaskTracker* task_tracker) { | |
24 scoped_ptr<SchedulerWorkerThread> worker_thread(new SchedulerWorkerThread( | |
25 thread_priority, main_entry_callback, get_work_callback, | |
26 ran_task_from_sequence_callback, task_tracker)); | |
27 | |
28 if (worker_thread->thread_handle_.is_null()) | |
29 return nullptr; | |
30 return worker_thread; | |
31 } | |
32 | |
33 SchedulerWorkerThread::~SchedulerWorkerThread() { | |
34 DCHECK(ShouldExitForTesting()); | |
35 } | |
36 | |
37 void SchedulerWorkerThread::WakeUp() { | |
38 wake_up_event_.Signal(); | |
gab
2016/04/05 23:35:20
Should this DCHECK(!wake_up_event_.IsSignaled());?
fdoray
2016/04/07 16:07:43
We support calls to WakeUp on an active thread. It
| |
39 } | |
40 | |
41 void SchedulerWorkerThread::JoinForTesting() { | |
42 { | |
43 AutoSchedulerLock auto_lock(should_exit_for_testing_lock_); | |
44 should_exit_for_testing_ = true; | |
45 } | |
46 WakeUp(); | |
47 PlatformThread::Join(thread_handle_); | |
48 } | |
49 | |
50 SchedulerWorkerThread::SchedulerWorkerThread( | |
51 ThreadPriority thread_priority, | |
52 const Closure& main_entry_callback, | |
53 const GetWorkCallback& get_work_callback, | |
54 const RanTaskFromSequenceCallback& ran_task_from_sequence_callback, | |
55 TaskTracker* task_tracker) | |
56 : wake_up_event_(false, false), | |
57 main_entry_callback_(main_entry_callback), | |
58 get_work_callback_(get_work_callback), | |
59 ran_task_from_sequence_callback_(ran_task_from_sequence_callback), | |
60 task_tracker_(task_tracker) { | |
61 DCHECK(!main_entry_callback_.is_null()); | |
62 DCHECK(!get_work_callback_.is_null()); | |
63 DCHECK(!ran_task_from_sequence_callback_.is_null()); | |
64 DCHECK(task_tracker_); | |
65 | |
66 static const size_t kDefaultStackSize = 0; | |
gab
2016/04/05 23:35:20
No need for "static" on non-compound local const t
fdoray
2016/04/07 16:07:43
Done.
| |
67 PlatformThread::CreateWithPriority(kDefaultStackSize, this, &thread_handle_, | |
68 thread_priority); | |
69 } | |
70 | |
71 void SchedulerWorkerThread::ThreadMain() { | |
72 main_entry_callback_.Run(); | |
73 | |
74 // A SchedulerWorkerThread starts out sleeping. | |
gab
2016/04/05 23:35:20
This should be mentioned in the API (header).
fdoray
2016/04/07 16:07:42
Done.
| |
75 wake_up_event_.Wait(); | |
76 | |
77 while (!task_tracker_->shutdown_completed() && !ShouldExitForTesting()) { | |
78 // Get the sequence containing the next task to execute. | |
79 scoped_refptr<Sequence> sequence = get_work_callback_.Run(this); | |
80 | |
81 if (!sequence) { | |
82 wake_up_event_.Wait(); | |
83 continue; | |
84 } | |
85 | |
86 task_tracker_->RunTask(sequence->PeekTask()); | |
87 ran_task_from_sequence_callback_.Run(this, std::move(sequence)); | |
88 | |
89 // Calling WakeUp() guarantees that this SchedulerWorkerThread will run | |
90 // Tasks from Sequences returned by |get_work_callback_| until the callback | |
91 // returns nullptr. Resetting |wake_up_event_| here doesn't break this | |
92 // invariant and avoids a useless loop iteration before going to sleep if | |
93 // WakeUp() is called while this SchedulerWorkerThread is awake. | |
94 wake_up_event_.Reset(); | |
95 } | |
96 } | |
97 | |
98 bool SchedulerWorkerThread::ShouldExitForTesting() const { | |
99 AutoSchedulerLock auto_lock(should_exit_for_testing_lock_); | |
100 return should_exit_for_testing_; | |
101 } | |
102 | |
103 } // namespace internal | |
104 } // namespace base | |
OLD | NEW |