OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/threading/sequenced_worker_pool.h" | 5 #include "base/threading/sequenced_worker_pool.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <list> | 9 #include <list> |
10 #include <map> | 10 #include <map> |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 | 86 |
87 explicit SequencedTask(const tracked_objects::Location& from_here) | 87 explicit SequencedTask(const tracked_objects::Location& from_here) |
88 : base::TrackingInfo(from_here, TimeTicks()), | 88 : base::TrackingInfo(from_here, TimeTicks()), |
89 sequence_token_id(0), | 89 sequence_token_id(0), |
90 trace_id(0), | 90 trace_id(0), |
91 sequence_task_number(0), | 91 sequence_task_number(0), |
92 shutdown_behavior(SequencedWorkerPool::BLOCK_SHUTDOWN) {} | 92 shutdown_behavior(SequencedWorkerPool::BLOCK_SHUTDOWN) {} |
93 | 93 |
94 ~SequencedTask() {} | 94 ~SequencedTask() {} |
95 | 95 |
| 96 SequencedTask(SequencedTask&&) = default; |
| 97 SequencedTask& operator=(SequencedTask&&) = default; |
| 98 |
96 int sequence_token_id; | 99 int sequence_token_id; |
97 int trace_id; | 100 int trace_id; |
98 int64_t sequence_task_number; | 101 int64_t sequence_task_number; |
99 SequencedWorkerPool::WorkerShutdown shutdown_behavior; | 102 SequencedWorkerPool::WorkerShutdown shutdown_behavior; |
100 tracked_objects::Location posted_from; | 103 tracked_objects::Location posted_from; |
101 Closure task; | 104 OnceClosure task; |
102 | 105 |
103 // Non-delayed tasks and delayed tasks are managed together by time-to-run | 106 // Non-delayed tasks and delayed tasks are managed together by time-to-run |
104 // order. We calculate the time by adding the posted time and the given delay. | 107 // order. We calculate the time by adding the posted time and the given delay. |
105 TimeTicks time_to_run; | 108 TimeTicks time_to_run; |
106 }; | 109 }; |
107 | 110 |
108 struct SequencedTaskLessThan { | 111 struct SequencedTaskLessThan { |
109 public: | 112 public: |
110 bool operator()(const SequencedTask& lhs, const SequencedTask& rhs) const { | 113 bool operator()(const SequencedTask& lhs, const SequencedTask& rhs) const { |
111 if (lhs.time_to_run < rhs.time_to_run) | 114 if (lhs.time_to_run < rhs.time_to_run) |
(...skipping 21 matching lines...) Expand all Loading... |
133 // | 136 // |
134 // Note that this class is RefCountedThreadSafe (inherited from TaskRunner). | 137 // Note that this class is RefCountedThreadSafe (inherited from TaskRunner). |
135 class SequencedWorkerPoolTaskRunner : public TaskRunner { | 138 class SequencedWorkerPoolTaskRunner : public TaskRunner { |
136 public: | 139 public: |
137 SequencedWorkerPoolTaskRunner( | 140 SequencedWorkerPoolTaskRunner( |
138 scoped_refptr<SequencedWorkerPool> pool, | 141 scoped_refptr<SequencedWorkerPool> pool, |
139 SequencedWorkerPool::WorkerShutdown shutdown_behavior); | 142 SequencedWorkerPool::WorkerShutdown shutdown_behavior); |
140 | 143 |
141 // TaskRunner implementation | 144 // TaskRunner implementation |
142 bool PostDelayedTask(const tracked_objects::Location& from_here, | 145 bool PostDelayedTask(const tracked_objects::Location& from_here, |
143 Closure task, | 146 OnceClosure task, |
144 TimeDelta delay) override; | 147 TimeDelta delay) override; |
145 bool RunsTasksOnCurrentThread() const override; | 148 bool RunsTasksOnCurrentThread() const override; |
146 | 149 |
147 private: | 150 private: |
148 ~SequencedWorkerPoolTaskRunner() override; | 151 ~SequencedWorkerPoolTaskRunner() override; |
149 | 152 |
150 const scoped_refptr<SequencedWorkerPool> pool_; | 153 const scoped_refptr<SequencedWorkerPool> pool_; |
151 | 154 |
152 const SequencedWorkerPool::WorkerShutdown shutdown_behavior_; | 155 const SequencedWorkerPool::WorkerShutdown shutdown_behavior_; |
153 | 156 |
154 DISALLOW_COPY_AND_ASSIGN(SequencedWorkerPoolTaskRunner); | 157 DISALLOW_COPY_AND_ASSIGN(SequencedWorkerPoolTaskRunner); |
155 }; | 158 }; |
156 | 159 |
157 SequencedWorkerPoolTaskRunner::SequencedWorkerPoolTaskRunner( | 160 SequencedWorkerPoolTaskRunner::SequencedWorkerPoolTaskRunner( |
158 scoped_refptr<SequencedWorkerPool> pool, | 161 scoped_refptr<SequencedWorkerPool> pool, |
159 SequencedWorkerPool::WorkerShutdown shutdown_behavior) | 162 SequencedWorkerPool::WorkerShutdown shutdown_behavior) |
160 : pool_(std::move(pool)), shutdown_behavior_(shutdown_behavior) {} | 163 : pool_(std::move(pool)), shutdown_behavior_(shutdown_behavior) {} |
161 | 164 |
162 SequencedWorkerPoolTaskRunner::~SequencedWorkerPoolTaskRunner() { | 165 SequencedWorkerPoolTaskRunner::~SequencedWorkerPoolTaskRunner() { |
163 } | 166 } |
164 | 167 |
165 bool SequencedWorkerPoolTaskRunner::PostDelayedTask( | 168 bool SequencedWorkerPoolTaskRunner::PostDelayedTask( |
166 const tracked_objects::Location& from_here, | 169 const tracked_objects::Location& from_here, |
167 Closure task, | 170 OnceClosure task, |
168 TimeDelta delay) { | 171 TimeDelta delay) { |
169 if (delay.is_zero()) { | 172 if (delay.is_zero()) { |
170 return pool_->PostWorkerTaskWithShutdownBehavior(from_here, std::move(task), | 173 return pool_->PostWorkerTaskWithShutdownBehavior(from_here, std::move(task), |
171 shutdown_behavior_); | 174 shutdown_behavior_); |
172 } | 175 } |
173 return pool_->PostDelayedWorkerTask(from_here, std::move(task), delay); | 176 return pool_->PostDelayedWorkerTask(from_here, std::move(task), delay); |
174 } | 177 } |
175 | 178 |
176 bool SequencedWorkerPoolTaskRunner::RunsTasksOnCurrentThread() const { | 179 bool SequencedWorkerPoolTaskRunner::RunsTasksOnCurrentThread() const { |
177 return pool_->RunsTasksOnCurrentThread(); | 180 return pool_->RunsTasksOnCurrentThread(); |
178 } | 181 } |
179 | 182 |
180 } // namespace | 183 } // namespace |
181 | 184 |
182 // SequencedWorkerPool::PoolSequencedTaskRunner ------------------------------ | 185 // SequencedWorkerPool::PoolSequencedTaskRunner ------------------------------ |
183 // A SequencedTaskRunner which posts tasks to a SequencedWorkerPool with a | 186 // A SequencedTaskRunner which posts tasks to a SequencedWorkerPool with a |
184 // fixed sequence token. | 187 // fixed sequence token. |
185 // | 188 // |
186 // Note that this class is RefCountedThreadSafe (inherited from TaskRunner). | 189 // Note that this class is RefCountedThreadSafe (inherited from TaskRunner). |
187 class SequencedWorkerPool::PoolSequencedTaskRunner | 190 class SequencedWorkerPool::PoolSequencedTaskRunner |
188 : public SequencedTaskRunner { | 191 : public SequencedTaskRunner { |
189 public: | 192 public: |
190 PoolSequencedTaskRunner( | 193 PoolSequencedTaskRunner( |
191 scoped_refptr<SequencedWorkerPool> pool, | 194 scoped_refptr<SequencedWorkerPool> pool, |
192 SequencedWorkerPool::SequenceToken token, | 195 SequencedWorkerPool::SequenceToken token, |
193 SequencedWorkerPool::WorkerShutdown shutdown_behavior); | 196 SequencedWorkerPool::WorkerShutdown shutdown_behavior); |
194 | 197 |
195 // TaskRunner implementation | 198 // TaskRunner implementation |
196 bool PostDelayedTask(const tracked_objects::Location& from_here, | 199 bool PostDelayedTask(const tracked_objects::Location& from_here, |
197 Closure task, | 200 OnceClosure task, |
198 TimeDelta delay) override; | 201 TimeDelta delay) override; |
199 bool RunsTasksOnCurrentThread() const override; | 202 bool RunsTasksOnCurrentThread() const override; |
200 | 203 |
201 // SequencedTaskRunner implementation | 204 // SequencedTaskRunner implementation |
202 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, | 205 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, |
203 Closure task, | 206 OnceClosure task, |
204 TimeDelta delay) override; | 207 TimeDelta delay) override; |
205 | 208 |
206 private: | 209 private: |
207 ~PoolSequencedTaskRunner() override; | 210 ~PoolSequencedTaskRunner() override; |
208 | 211 |
209 const scoped_refptr<SequencedWorkerPool> pool_; | 212 const scoped_refptr<SequencedWorkerPool> pool_; |
210 | 213 |
211 const SequencedWorkerPool::SequenceToken token_; | 214 const SequencedWorkerPool::SequenceToken token_; |
212 | 215 |
213 const SequencedWorkerPool::WorkerShutdown shutdown_behavior_; | 216 const SequencedWorkerPool::WorkerShutdown shutdown_behavior_; |
214 | 217 |
215 DISALLOW_COPY_AND_ASSIGN(PoolSequencedTaskRunner); | 218 DISALLOW_COPY_AND_ASSIGN(PoolSequencedTaskRunner); |
216 }; | 219 }; |
217 | 220 |
218 SequencedWorkerPool::PoolSequencedTaskRunner:: | 221 SequencedWorkerPool::PoolSequencedTaskRunner:: |
219 PoolSequencedTaskRunner( | 222 PoolSequencedTaskRunner( |
220 scoped_refptr<SequencedWorkerPool> pool, | 223 scoped_refptr<SequencedWorkerPool> pool, |
221 SequencedWorkerPool::SequenceToken token, | 224 SequencedWorkerPool::SequenceToken token, |
222 SequencedWorkerPool::WorkerShutdown shutdown_behavior) | 225 SequencedWorkerPool::WorkerShutdown shutdown_behavior) |
223 : pool_(std::move(pool)), | 226 : pool_(std::move(pool)), |
224 token_(token), | 227 token_(token), |
225 shutdown_behavior_(shutdown_behavior) {} | 228 shutdown_behavior_(shutdown_behavior) {} |
226 | 229 |
227 SequencedWorkerPool::PoolSequencedTaskRunner:: | 230 SequencedWorkerPool::PoolSequencedTaskRunner:: |
228 ~PoolSequencedTaskRunner() = default; | 231 ~PoolSequencedTaskRunner() = default; |
229 | 232 |
230 bool SequencedWorkerPool::PoolSequencedTaskRunner::PostDelayedTask( | 233 bool SequencedWorkerPool::PoolSequencedTaskRunner::PostDelayedTask( |
231 const tracked_objects::Location& from_here, | 234 const tracked_objects::Location& from_here, |
232 Closure task, | 235 OnceClosure task, |
233 TimeDelta delay) { | 236 TimeDelta delay) { |
234 if (delay.is_zero()) { | 237 if (delay.is_zero()) { |
235 return pool_->PostSequencedWorkerTaskWithShutdownBehavior( | 238 return pool_->PostSequencedWorkerTaskWithShutdownBehavior( |
236 token_, from_here, std::move(task), shutdown_behavior_); | 239 token_, from_here, std::move(task), shutdown_behavior_); |
237 } | 240 } |
238 return pool_->PostDelayedSequencedWorkerTask(token_, from_here, | 241 return pool_->PostDelayedSequencedWorkerTask(token_, from_here, |
239 std::move(task), delay); | 242 std::move(task), delay); |
240 } | 243 } |
241 | 244 |
242 bool SequencedWorkerPool::PoolSequencedTaskRunner:: | 245 bool SequencedWorkerPool::PoolSequencedTaskRunner:: |
243 RunsTasksOnCurrentThread() const { | 246 RunsTasksOnCurrentThread() const { |
244 return pool_->IsRunningSequenceOnCurrentThread(token_); | 247 return pool_->IsRunningSequenceOnCurrentThread(token_); |
245 } | 248 } |
246 | 249 |
247 bool SequencedWorkerPool::PoolSequencedTaskRunner::PostNonNestableDelayedTask( | 250 bool SequencedWorkerPool::PoolSequencedTaskRunner::PostNonNestableDelayedTask( |
248 const tracked_objects::Location& from_here, | 251 const tracked_objects::Location& from_here, |
249 Closure task, | 252 OnceClosure task, |
250 TimeDelta delay) { | 253 TimeDelta delay) { |
251 // There's no way to run nested tasks, so simply forward to | 254 // There's no way to run nested tasks, so simply forward to |
252 // PostDelayedTask. | 255 // PostDelayedTask. |
253 return PostDelayedTask(from_here, std::move(task), delay); | 256 return PostDelayedTask(from_here, std::move(task), delay); |
254 } | 257 } |
255 | 258 |
256 // Worker --------------------------------------------------------------------- | 259 // Worker --------------------------------------------------------------------- |
257 | 260 |
258 class SequencedWorkerPool::Worker : public SimpleThread { | 261 class SequencedWorkerPool::Worker : public SimpleThread { |
259 public: | 262 public: |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 | 345 |
343 SequenceToken GetNamedSequenceToken(const std::string& name); | 346 SequenceToken GetNamedSequenceToken(const std::string& name); |
344 | 347 |
345 // This function accepts a name and an ID. If the name is null, the | 348 // This function accepts a name and an ID. If the name is null, the |
346 // token ID is used. This allows us to implement the optional name lookup | 349 // token ID is used. This allows us to implement the optional name lookup |
347 // from a single function without having to enter the lock a separate time. | 350 // from a single function without having to enter the lock a separate time. |
348 bool PostTask(const std::string* optional_token_name, | 351 bool PostTask(const std::string* optional_token_name, |
349 SequenceToken sequence_token, | 352 SequenceToken sequence_token, |
350 WorkerShutdown shutdown_behavior, | 353 WorkerShutdown shutdown_behavior, |
351 const tracked_objects::Location& from_here, | 354 const tracked_objects::Location& from_here, |
352 Closure task, | 355 OnceClosure task, |
353 TimeDelta delay); | 356 TimeDelta delay); |
354 | 357 |
355 bool RunsTasksOnCurrentThread() const; | 358 bool RunsTasksOnCurrentThread() const; |
356 | 359 |
357 bool IsRunningSequenceOnCurrentThread(SequenceToken sequence_token) const; | 360 bool IsRunningSequenceOnCurrentThread(SequenceToken sequence_token) const; |
358 | 361 |
359 void CleanupForTesting(); | 362 void CleanupForTesting(); |
360 | 363 |
361 void SignalHasWorkForTesting(); | 364 void SignalHasWorkForTesting(); |
362 | 365 |
(...skipping 24 matching lines...) Expand all Loading... |
387 // Clears ScheduledTasks in |tasks_to_delete| while ensuring that | 390 // Clears ScheduledTasks in |tasks_to_delete| while ensuring that |
388 // |this_worker| has the desired task info context during ~ScheduledTask() to | 391 // |this_worker| has the desired task info context during ~ScheduledTask() to |
389 // allow sequence-checking. | 392 // allow sequence-checking. |
390 void DeleteWithoutLock(std::vector<SequencedTask>* tasks_to_delete, | 393 void DeleteWithoutLock(std::vector<SequencedTask>* tasks_to_delete, |
391 Worker* this_worker); | 394 Worker* this_worker); |
392 | 395 |
393 // Helper used by PostTask() to complete the work when redirection is on. | 396 // Helper used by PostTask() to complete the work when redirection is on. |
394 // Returns true if the task may run at some point in the future and false if | 397 // Returns true if the task may run at some point in the future and false if |
395 // it will definitely not run. | 398 // it will definitely not run. |
396 // Coalesce upon resolution of http://crbug.com/622400. | 399 // Coalesce upon resolution of http://crbug.com/622400. |
397 bool PostTaskToTaskScheduler(const SequencedTask& sequenced, | 400 bool PostTaskToTaskScheduler(SequencedTask sequenced, const TimeDelta& delay); |
398 const TimeDelta& delay); | |
399 | 401 |
400 // Returns the TaskScheduler TaskRunner for the specified |sequence_token_id| | 402 // Returns the TaskScheduler TaskRunner for the specified |sequence_token_id| |
401 // and |traits|. | 403 // and |traits|. |
402 scoped_refptr<TaskRunner> GetTaskSchedulerTaskRunner( | 404 scoped_refptr<TaskRunner> GetTaskSchedulerTaskRunner( |
403 int sequence_token_id, | 405 int sequence_token_id, |
404 const TaskTraits& traits); | 406 const TaskTraits& traits); |
405 | 407 |
406 // Called from within the lock, this converts the given token name into a | 408 // Called from within the lock, this converts the given token name into a |
407 // token ID, creating a new one if necessary. | 409 // token ID, creating a new one if necessary. |
408 int LockedGetNamedTokenID(const std::string& name); | 410 int LockedGetNamedTokenID(const std::string& name); |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
686 SequencedWorkerPool::Inner::GetNamedSequenceToken(const std::string& name) { | 688 SequencedWorkerPool::Inner::GetNamedSequenceToken(const std::string& name) { |
687 AutoLock lock(lock_); | 689 AutoLock lock(lock_); |
688 return SequenceToken(LockedGetNamedTokenID(name)); | 690 return SequenceToken(LockedGetNamedTokenID(name)); |
689 } | 691 } |
690 | 692 |
691 bool SequencedWorkerPool::Inner::PostTask( | 693 bool SequencedWorkerPool::Inner::PostTask( |
692 const std::string* optional_token_name, | 694 const std::string* optional_token_name, |
693 SequenceToken sequence_token, | 695 SequenceToken sequence_token, |
694 WorkerShutdown shutdown_behavior, | 696 WorkerShutdown shutdown_behavior, |
695 const tracked_objects::Location& from_here, | 697 const tracked_objects::Location& from_here, |
696 Closure task, | 698 OnceClosure task, |
697 TimeDelta delay) { | 699 TimeDelta delay) { |
698 DCHECK(task); | 700 DCHECK(task); |
699 | 701 |
700 // TODO(fdoray): Uncomment this DCHECK. It is initially commented to avoid a | 702 // TODO(fdoray): Uncomment this DCHECK. It is initially commented to avoid a |
701 // revert of the CL that adds debug::DumpWithoutCrashing() if it fails on the | 703 // revert of the CL that adds debug::DumpWithoutCrashing() if it fails on the |
702 // waterfall. https://crbug.com/622400 | 704 // waterfall. https://crbug.com/622400 |
703 // DCHECK_NE(AllPoolsState::POST_TASK_DISABLED, g_all_pools_state); | 705 // DCHECK_NE(AllPoolsState::POST_TASK_DISABLED, g_all_pools_state); |
704 if (g_all_pools_state == AllPoolsState::POST_TASK_DISABLED) | 706 if (g_all_pools_state == AllPoolsState::POST_TASK_DISABLED) |
705 debug::DumpWithoutCrashing(); | 707 debug::DumpWithoutCrashing(); |
706 | 708 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
747 TRACE_ID_MANGLE(GetTaskTraceID(sequenced, static_cast<void*>(this))), | 749 TRACE_ID_MANGLE(GetTaskTraceID(sequenced, static_cast<void*>(this))), |
748 TRACE_EVENT_FLAG_FLOW_OUT); | 750 TRACE_EVENT_FLAG_FLOW_OUT); |
749 | 751 |
750 sequenced.sequence_task_number = LockedGetNextSequenceTaskNumber(); | 752 sequenced.sequence_task_number = LockedGetNextSequenceTaskNumber(); |
751 | 753 |
752 // Now that we have the lock, apply the named token rules. | 754 // Now that we have the lock, apply the named token rules. |
753 if (optional_token_name) | 755 if (optional_token_name) |
754 sequenced.sequence_token_id = LockedGetNamedTokenID(*optional_token_name); | 756 sequenced.sequence_token_id = LockedGetNamedTokenID(*optional_token_name); |
755 | 757 |
756 if (g_all_pools_state == AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) { | 758 if (g_all_pools_state == AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) { |
757 if (!PostTaskToTaskScheduler(sequenced, delay)) | 759 if (!PostTaskToTaskScheduler(std::move(sequenced), delay)) |
758 return false; | 760 return false; |
759 } else { | 761 } else { |
760 pending_tasks_.insert(sequenced); | 762 SequencedWorkerPool::WorkerShutdown shutdown_behavior = |
| 763 sequenced.shutdown_behavior; |
| 764 pending_tasks_.insert(std::move(sequenced)); |
761 | 765 |
762 if (sequenced.shutdown_behavior == BLOCK_SHUTDOWN) | 766 if (shutdown_behavior == BLOCK_SHUTDOWN) |
763 blocking_shutdown_pending_task_count_++; | 767 blocking_shutdown_pending_task_count_++; |
764 | 768 |
765 create_thread_id = PrepareToStartAdditionalThreadIfHelpful(); | 769 create_thread_id = PrepareToStartAdditionalThreadIfHelpful(); |
766 } | 770 } |
767 } | 771 } |
768 | 772 |
769 // Use != REDIRECTED_TO_TASK_SCHEDULER instead of == USE_WORKER_POOL to ensure | 773 // Use != REDIRECTED_TO_TASK_SCHEDULER instead of == USE_WORKER_POOL to ensure |
770 // correct behavior if a task is posted to a SequencedWorkerPool before | 774 // correct behavior if a task is posted to a SequencedWorkerPool before |
771 // Enable(WithRedirectionToTaskScheduler)ForProcess() in a non-DCHECK build. | 775 // Enable(WithRedirectionToTaskScheduler)ForProcess() in a non-DCHECK build. |
772 if (g_all_pools_state != AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) { | 776 if (g_all_pools_state != AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) { |
(...skipping 16 matching lines...) Expand all Loading... |
789 } else { | 793 } else { |
790 DCHECK(sequenced_task_runner_map_.empty()); | 794 DCHECK(sequenced_task_runner_map_.empty()); |
791 } | 795 } |
792 } | 796 } |
793 #endif // DCHECK_IS_ON() | 797 #endif // DCHECK_IS_ON() |
794 | 798 |
795 return true; | 799 return true; |
796 } | 800 } |
797 | 801 |
798 bool SequencedWorkerPool::Inner::PostTaskToTaskScheduler( | 802 bool SequencedWorkerPool::Inner::PostTaskToTaskScheduler( |
799 const SequencedTask& sequenced, | 803 SequencedTask sequenced, |
800 const TimeDelta& delay) { | 804 const TimeDelta& delay) { |
801 DCHECK_EQ(AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER, g_all_pools_state); | 805 DCHECK_EQ(AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER, g_all_pools_state); |
802 | 806 |
803 lock_.AssertAcquired(); | 807 lock_.AssertAcquired(); |
804 | 808 |
805 // Confirm that the TaskScheduler's shutdown behaviors use the same | 809 // Confirm that the TaskScheduler's shutdown behaviors use the same |
806 // underlying values as SequencedWorkerPool. | 810 // underlying values as SequencedWorkerPool. |
807 static_assert( | 811 static_assert( |
808 static_cast<int>(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) == | 812 static_cast<int>(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) == |
809 static_cast<int>(CONTINUE_ON_SHUTDOWN), | 813 static_cast<int>(CONTINUE_ON_SHUTDOWN), |
810 "TaskShutdownBehavior and WorkerShutdown enum mismatch for " | 814 "TaskShutdownBehavior and WorkerShutdown enum mismatch for " |
811 "CONTINUE_ON_SHUTDOWN."); | 815 "CONTINUE_ON_SHUTDOWN."); |
812 static_assert(static_cast<int>(TaskShutdownBehavior::SKIP_ON_SHUTDOWN) == | 816 static_assert(static_cast<int>(TaskShutdownBehavior::SKIP_ON_SHUTDOWN) == |
813 static_cast<int>(SKIP_ON_SHUTDOWN), | 817 static_cast<int>(SKIP_ON_SHUTDOWN), |
814 "TaskShutdownBehavior and WorkerShutdown enum mismatch for " | 818 "TaskShutdownBehavior and WorkerShutdown enum mismatch for " |
815 "SKIP_ON_SHUTDOWN."); | 819 "SKIP_ON_SHUTDOWN."); |
816 static_assert(static_cast<int>(TaskShutdownBehavior::BLOCK_SHUTDOWN) == | 820 static_assert(static_cast<int>(TaskShutdownBehavior::BLOCK_SHUTDOWN) == |
817 static_cast<int>(BLOCK_SHUTDOWN), | 821 static_cast<int>(BLOCK_SHUTDOWN), |
818 "TaskShutdownBehavior and WorkerShutdown enum mismatch for " | 822 "TaskShutdownBehavior and WorkerShutdown enum mismatch for " |
819 "BLOCK_SHUTDOWN."); | 823 "BLOCK_SHUTDOWN."); |
820 | 824 |
821 const TaskShutdownBehavior task_shutdown_behavior = | 825 const TaskShutdownBehavior task_shutdown_behavior = |
822 static_cast<TaskShutdownBehavior>(sequenced.shutdown_behavior); | 826 static_cast<TaskShutdownBehavior>(sequenced.shutdown_behavior); |
823 const TaskTraits traits = TaskTraits() | 827 const TaskTraits traits = TaskTraits() |
824 .MayBlock() | 828 .MayBlock() |
825 .WithBaseSyncPrimitives() | 829 .WithBaseSyncPrimitives() |
826 .WithPriority(task_priority_) | 830 .WithPriority(task_priority_) |
827 .WithShutdownBehavior(task_shutdown_behavior); | 831 .WithShutdownBehavior(task_shutdown_behavior); |
828 return GetTaskSchedulerTaskRunner(sequenced.sequence_token_id, traits) | 832 return GetTaskSchedulerTaskRunner(sequenced.sequence_token_id, traits) |
829 ->PostDelayedTask(sequenced.posted_from, sequenced.task, delay); | 833 ->PostDelayedTask(sequenced.posted_from, std::move(sequenced.task), |
| 834 delay); |
830 } | 835 } |
831 | 836 |
832 scoped_refptr<TaskRunner> | 837 scoped_refptr<TaskRunner> |
833 SequencedWorkerPool::Inner::GetTaskSchedulerTaskRunner( | 838 SequencedWorkerPool::Inner::GetTaskSchedulerTaskRunner( |
834 int sequence_token_id, | 839 int sequence_token_id, |
835 const TaskTraits& traits) { | 840 const TaskTraits& traits) { |
836 DCHECK_EQ(AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER, g_all_pools_state); | 841 DCHECK_EQ(AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER, g_all_pools_state); |
837 | 842 |
838 lock_.AssertAcquired(); | 843 lock_.AssertAcquired(); |
839 | 844 |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1237 // can have side effects (like freeing some objects) and deleting a task | 1242 // can have side effects (like freeing some objects) and deleting a task |
1238 // that's supposed to run after one that's currently running could cause | 1243 // that's supposed to run after one that's currently running could cause |
1239 // an obscure crash. | 1244 // an obscure crash. |
1240 // | 1245 // |
1241 // We really want to delete these tasks outside the lock in case the | 1246 // We really want to delete these tasks outside the lock in case the |
1242 // closures are holding refs to objects that want to post work from their | 1247 // closures are holding refs to objects that want to post work from their |
1243 // destructors (which would deadlock). The closures are internally | 1248 // destructors (which would deadlock). The closures are internally |
1244 // refcounted, so we just need to keep a copy of them alive until the lock | 1249 // refcounted, so we just need to keep a copy of them alive until the lock |
1245 // is exited. The calling code can just clear() the vector they passed to | 1250 // is exited. The calling code can just clear() the vector they passed to |
1246 // us once the lock is exited to make this happen. | 1251 // us once the lock is exited to make this happen. |
1247 delete_these_outside_lock->push_back(*i); | 1252 // |
| 1253 // The const_cast here is safe since the object is erased from |
| 1254 // |pending_tasks_| soon after the move. |
| 1255 delete_these_outside_lock->push_back( |
| 1256 std::move(const_cast<SequencedTask&>(*i))); |
1248 pending_tasks_.erase(i++); | 1257 pending_tasks_.erase(i++); |
1249 continue; | 1258 continue; |
1250 } | 1259 } |
1251 | 1260 |
1252 if (i->time_to_run > current_time) { | 1261 if (i->time_to_run > current_time) { |
1253 // The time to run has not come yet. | 1262 // The time to run has not come yet. |
1254 *wait_time = i->time_to_run - current_time; | 1263 *wait_time = i->time_to_run - current_time; |
1255 status = GET_WORK_WAIT; | 1264 status = GET_WORK_WAIT; |
1256 if (cleanup_state_ == CLEANUP_RUNNING) { | 1265 if (cleanup_state_ == CLEANUP_RUNNING) { |
1257 // Deferred tasks are deleted when cleaning up, see Inner::ThreadLoop. | 1266 // Deferred tasks are deleted when cleaning up, see Inner::ThreadLoop. |
1258 delete_these_outside_lock->push_back(*i); | 1267 // The const_cast here is safe since the object is erased from |
| 1268 // |pending_tasks_| soon after the move. |
| 1269 delete_these_outside_lock->push_back( |
| 1270 std::move(const_cast<SequencedTask&>(*i))); |
1259 pending_tasks_.erase(i); | 1271 pending_tasks_.erase(i); |
1260 } | 1272 } |
1261 break; | 1273 break; |
1262 } | 1274 } |
1263 | 1275 |
1264 // Found a runnable task. | 1276 // Found a runnable task. The const_cast is safe here since the object is |
1265 *task = *i; | 1277 // erased from |pending_tasks_| soon after the move. |
| 1278 *task = std::move(const_cast<SequencedTask&>(*i)); |
1266 pending_tasks_.erase(i); | 1279 pending_tasks_.erase(i); |
1267 if (task->shutdown_behavior == BLOCK_SHUTDOWN) { | 1280 if (task->shutdown_behavior == BLOCK_SHUTDOWN) { |
1268 blocking_shutdown_pending_task_count_--; | 1281 blocking_shutdown_pending_task_count_--; |
1269 } | 1282 } |
1270 | 1283 |
1271 status = GET_WORK_FOUND; | 1284 status = GET_WORK_FOUND; |
1272 break; | 1285 break; |
1273 } | 1286 } |
1274 | 1287 |
1275 return status; | 1288 return status; |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1528 } | 1541 } |
1529 | 1542 |
1530 scoped_refptr<TaskRunner> | 1543 scoped_refptr<TaskRunner> |
1531 SequencedWorkerPool::GetTaskRunnerWithShutdownBehavior( | 1544 SequencedWorkerPool::GetTaskRunnerWithShutdownBehavior( |
1532 WorkerShutdown shutdown_behavior) { | 1545 WorkerShutdown shutdown_behavior) { |
1533 return new SequencedWorkerPoolTaskRunner(this, shutdown_behavior); | 1546 return new SequencedWorkerPoolTaskRunner(this, shutdown_behavior); |
1534 } | 1547 } |
1535 | 1548 |
1536 bool SequencedWorkerPool::PostWorkerTask( | 1549 bool SequencedWorkerPool::PostWorkerTask( |
1537 const tracked_objects::Location& from_here, | 1550 const tracked_objects::Location& from_here, |
1538 Closure task) { | 1551 OnceClosure task) { |
1539 return inner_->PostTask(NULL, SequenceToken(), BLOCK_SHUTDOWN, from_here, | 1552 return inner_->PostTask(NULL, SequenceToken(), BLOCK_SHUTDOWN, from_here, |
1540 std::move(task), TimeDelta()); | 1553 std::move(task), TimeDelta()); |
1541 } | 1554 } |
1542 | 1555 |
1543 bool SequencedWorkerPool::PostDelayedWorkerTask( | 1556 bool SequencedWorkerPool::PostDelayedWorkerTask( |
1544 const tracked_objects::Location& from_here, | 1557 const tracked_objects::Location& from_here, |
1545 Closure task, | 1558 OnceClosure task, |
1546 TimeDelta delay) { | 1559 TimeDelta delay) { |
1547 WorkerShutdown shutdown_behavior = | 1560 WorkerShutdown shutdown_behavior = |
1548 delay.is_zero() ? BLOCK_SHUTDOWN : SKIP_ON_SHUTDOWN; | 1561 delay.is_zero() ? BLOCK_SHUTDOWN : SKIP_ON_SHUTDOWN; |
1549 return inner_->PostTask(NULL, SequenceToken(), shutdown_behavior, from_here, | 1562 return inner_->PostTask(NULL, SequenceToken(), shutdown_behavior, from_here, |
1550 std::move(task), delay); | 1563 std::move(task), delay); |
1551 } | 1564 } |
1552 | 1565 |
1553 bool SequencedWorkerPool::PostWorkerTaskWithShutdownBehavior( | 1566 bool SequencedWorkerPool::PostWorkerTaskWithShutdownBehavior( |
1554 const tracked_objects::Location& from_here, | 1567 const tracked_objects::Location& from_here, |
1555 Closure task, | 1568 OnceClosure task, |
1556 WorkerShutdown shutdown_behavior) { | 1569 WorkerShutdown shutdown_behavior) { |
1557 return inner_->PostTask(NULL, SequenceToken(), shutdown_behavior, from_here, | 1570 return inner_->PostTask(NULL, SequenceToken(), shutdown_behavior, from_here, |
1558 std::move(task), TimeDelta()); | 1571 std::move(task), TimeDelta()); |
1559 } | 1572 } |
1560 | 1573 |
1561 bool SequencedWorkerPool::PostSequencedWorkerTask( | 1574 bool SequencedWorkerPool::PostSequencedWorkerTask( |
1562 SequenceToken sequence_token, | 1575 SequenceToken sequence_token, |
1563 const tracked_objects::Location& from_here, | 1576 const tracked_objects::Location& from_here, |
1564 Closure task) { | 1577 OnceClosure task) { |
1565 return inner_->PostTask(NULL, sequence_token, BLOCK_SHUTDOWN, from_here, | 1578 return inner_->PostTask(NULL, sequence_token, BLOCK_SHUTDOWN, from_here, |
1566 std::move(task), TimeDelta()); | 1579 std::move(task), TimeDelta()); |
1567 } | 1580 } |
1568 | 1581 |
1569 bool SequencedWorkerPool::PostDelayedSequencedWorkerTask( | 1582 bool SequencedWorkerPool::PostDelayedSequencedWorkerTask( |
1570 SequenceToken sequence_token, | 1583 SequenceToken sequence_token, |
1571 const tracked_objects::Location& from_here, | 1584 const tracked_objects::Location& from_here, |
1572 Closure task, | 1585 OnceClosure task, |
1573 TimeDelta delay) { | 1586 TimeDelta delay) { |
1574 WorkerShutdown shutdown_behavior = | 1587 WorkerShutdown shutdown_behavior = |
1575 delay.is_zero() ? BLOCK_SHUTDOWN : SKIP_ON_SHUTDOWN; | 1588 delay.is_zero() ? BLOCK_SHUTDOWN : SKIP_ON_SHUTDOWN; |
1576 return inner_->PostTask(NULL, sequence_token, shutdown_behavior, from_here, | 1589 return inner_->PostTask(NULL, sequence_token, shutdown_behavior, from_here, |
1577 std::move(task), delay); | 1590 std::move(task), delay); |
1578 } | 1591 } |
1579 | 1592 |
1580 bool SequencedWorkerPool::PostNamedSequencedWorkerTask( | 1593 bool SequencedWorkerPool::PostNamedSequencedWorkerTask( |
1581 const std::string& token_name, | 1594 const std::string& token_name, |
1582 const tracked_objects::Location& from_here, | 1595 const tracked_objects::Location& from_here, |
1583 Closure task) { | 1596 OnceClosure task) { |
1584 DCHECK(!token_name.empty()); | 1597 DCHECK(!token_name.empty()); |
1585 return inner_->PostTask(&token_name, SequenceToken(), BLOCK_SHUTDOWN, | 1598 return inner_->PostTask(&token_name, SequenceToken(), BLOCK_SHUTDOWN, |
1586 from_here, std::move(task), TimeDelta()); | 1599 from_here, std::move(task), TimeDelta()); |
1587 } | 1600 } |
1588 | 1601 |
1589 bool SequencedWorkerPool::PostSequencedWorkerTaskWithShutdownBehavior( | 1602 bool SequencedWorkerPool::PostSequencedWorkerTaskWithShutdownBehavior( |
1590 SequenceToken sequence_token, | 1603 SequenceToken sequence_token, |
1591 const tracked_objects::Location& from_here, | 1604 const tracked_objects::Location& from_here, |
1592 Closure task, | 1605 OnceClosure task, |
1593 WorkerShutdown shutdown_behavior) { | 1606 WorkerShutdown shutdown_behavior) { |
1594 return inner_->PostTask(NULL, sequence_token, shutdown_behavior, from_here, | 1607 return inner_->PostTask(NULL, sequence_token, shutdown_behavior, from_here, |
1595 std::move(task), TimeDelta()); | 1608 std::move(task), TimeDelta()); |
1596 } | 1609 } |
1597 | 1610 |
1598 bool SequencedWorkerPool::PostDelayedTask( | 1611 bool SequencedWorkerPool::PostDelayedTask( |
1599 const tracked_objects::Location& from_here, | 1612 const tracked_objects::Location& from_here, |
1600 Closure task, | 1613 OnceClosure task, |
1601 TimeDelta delay) { | 1614 TimeDelta delay) { |
1602 return PostDelayedWorkerTask(from_here, std::move(task), delay); | 1615 return PostDelayedWorkerTask(from_here, std::move(task), delay); |
1603 } | 1616 } |
1604 | 1617 |
1605 bool SequencedWorkerPool::RunsTasksOnCurrentThread() const { | 1618 bool SequencedWorkerPool::RunsTasksOnCurrentThread() const { |
1606 return inner_->RunsTasksOnCurrentThread(); | 1619 return inner_->RunsTasksOnCurrentThread(); |
1607 } | 1620 } |
1608 | 1621 |
1609 void SequencedWorkerPool::FlushForTesting() { | 1622 void SequencedWorkerPool::FlushForTesting() { |
1610 DCHECK(!RunsTasksOnCurrentThread()); | 1623 DCHECK(!RunsTasksOnCurrentThread()); |
(...skipping 18 matching lines...) Expand all Loading... |
1629 bool SequencedWorkerPool::IsShutdownInProgress() { | 1642 bool SequencedWorkerPool::IsShutdownInProgress() { |
1630 return inner_->IsShutdownInProgress(); | 1643 return inner_->IsShutdownInProgress(); |
1631 } | 1644 } |
1632 | 1645 |
1633 bool SequencedWorkerPool::IsRunningSequenceOnCurrentThread( | 1646 bool SequencedWorkerPool::IsRunningSequenceOnCurrentThread( |
1634 SequenceToken sequence_token) const { | 1647 SequenceToken sequence_token) const { |
1635 return inner_->IsRunningSequenceOnCurrentThread(sequence_token); | 1648 return inner_->IsRunningSequenceOnCurrentThread(sequence_token); |
1636 } | 1649 } |
1637 | 1650 |
1638 } // namespace base | 1651 } // namespace base |
OLD | NEW |