| OLD | NEW |
| 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/task_tracker.h" | 5 #include "base/task_scheduler/task_tracker.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/debug/task_annotator.h" | 10 #include "base/debug/task_annotator.h" |
| 11 #include "base/json/json_writer.h" | 11 #include "base/json/json_writer.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
| 14 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
| 15 #include "base/sequence_token.h" | 15 #include "base/sequence_token.h" |
| 16 #include "base/synchronization/condition_variable.h" | 16 #include "base/synchronization/condition_variable.h" |
| 17 #include "base/threading/sequenced_task_runner_handle.h" | 17 #include "base/threading/sequenced_task_runner_handle.h" |
| 18 #include "base/threading/thread_restrictions.h" | 18 #include "base/threading/thread_restrictions.h" |
| 19 #include "base/threading/thread_task_runner_handle.h" | 19 #include "base/threading/thread_task_runner_handle.h" |
| 20 #include "base/trace_event/trace_event.h" | 20 #include "base/trace_event/trace_event.h" |
| 21 #include "base/values.h" | 21 #include "base/values.h" |
| 22 | 22 |
| 23 #if defined(OS_POSIX) && !defined(OS_NACL_SFI) |
| 24 #include "base/files/file_descriptor_watcher_posix.h" |
| 25 #endif |
| 26 |
| 23 namespace base { | 27 namespace base { |
| 24 namespace internal { | 28 namespace internal { |
| 25 | 29 |
| 26 namespace { | 30 namespace { |
| 27 | 31 |
| 28 // An immutable copy of a scheduler task's info required by tracing. | 32 // An immutable copy of a scheduler task's info required by tracing. |
| 29 class TaskTracingInfo : public trace_event::ConvertableToTraceFormat { | 33 class TaskTracingInfo : public trace_event::ConvertableToTraceFormat { |
| 30 public: | 34 public: |
| 31 TaskTracingInfo(const TaskTraits& task_traits, | 35 TaskTracingInfo(const TaskTraits& task_traits, |
| 32 ExecutionMode execution_mode, | 36 ExecutionMode execution_mode, |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 // modify-write) semantics however. For example, if two threads are racing to | 164 // modify-write) semantics however. For example, if two threads are racing to |
| 161 // call IncrementNumTasksBlockingShutdown() and StartShutdown() respectively, | 165 // call IncrementNumTasksBlockingShutdown() and StartShutdown() respectively, |
| 162 // either the first thread will win and the StartShutdown() call will see the | 166 // either the first thread will win and the StartShutdown() call will see the |
| 163 // blocking task or the second thread will win and | 167 // blocking task or the second thread will win and |
| 164 // IncrementNumTasksBlockingShutdown() will know that shutdown has started. | 168 // IncrementNumTasksBlockingShutdown() will know that shutdown has started. |
| 165 subtle::Atomic32 bits_ = 0; | 169 subtle::Atomic32 bits_ = 0; |
| 166 | 170 |
| 167 DISALLOW_COPY_AND_ASSIGN(State); | 171 DISALLOW_COPY_AND_ASSIGN(State); |
| 168 }; | 172 }; |
| 169 | 173 |
| 170 TaskTracker::TaskTracker() | 174 TaskTracker::TaskTracker( |
| 175 #if defined(OS_POSIX) && !defined(OS_NACL_SFI) |
| 176 MessageLoopForIO* watch_file_descriptor_message_loop |
| 177 #endif |
| 178 ) |
| 171 : state_(new State), | 179 : state_(new State), |
| 172 flush_cv_(flush_lock_.CreateConditionVariable()), | 180 flush_cv_(flush_lock_.CreateConditionVariable()), |
| 173 shutdown_lock_(&flush_lock_) {} | 181 shutdown_lock_(&flush_lock_) |
| 182 #if defined(OS_POSIX) && !defined(OS_NACL_SFI) |
| 183 , |
| 184 watch_file_descriptor_message_loop_(watch_file_descriptor_message_loop) |
| 185 #endif |
| 186 { |
| 187 #if defined(OS_POSIX) && !defined(OS_NACL_SFI) |
| 188 DCHECK(watch_file_descriptor_message_loop_); |
| 189 #endif |
| 190 } |
| 174 TaskTracker::~TaskTracker() = default; | 191 TaskTracker::~TaskTracker() = default; |
| 175 | 192 |
| 176 void TaskTracker::Shutdown() { | 193 void TaskTracker::Shutdown() { |
| 177 PerformShutdown(); | 194 PerformShutdown(); |
| 178 DCHECK(IsShutdownComplete()); | 195 DCHECK(IsShutdownComplete()); |
| 179 | 196 |
| 180 // Unblock Flush() when shutdown completes. | 197 // Unblock Flush() when shutdown completes. |
| 181 AutoSchedulerLock auto_lock(flush_lock_); | 198 AutoSchedulerLock auto_lock(flush_lock_); |
| 182 flush_cv_->Signal(); | 199 flush_cv_->Signal(); |
| 183 } | 200 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 | 233 |
| 217 if (can_run_task) { | 234 if (can_run_task) { |
| 218 // All tasks run through here and the scheduler itself doesn't use | 235 // All tasks run through here and the scheduler itself doesn't use |
| 219 // singletons. Therefore, it isn't necessary to reset the singleton allowed | 236 // singletons. Therefore, it isn't necessary to reset the singleton allowed |
| 220 // bit after running the task. | 237 // bit after running the task. |
| 221 ThreadRestrictions::SetSingletonAllowed( | 238 ThreadRestrictions::SetSingletonAllowed( |
| 222 task->traits.shutdown_behavior() != | 239 task->traits.shutdown_behavior() != |
| 223 TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN); | 240 TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN); |
| 224 | 241 |
| 225 { | 242 { |
| 243 #if defined(OS_POSIX) && !defined(OS_NACL_SFI) |
| 244 // Support FileDescriptorWatcher for the scope of the task. |
| 245 FileDescriptorWatcher file_descriptor_watcher( |
| 246 watch_file_descriptor_message_loop_); |
| 247 #endif |
| 248 |
| 226 // Set up SequenceToken as expected for the scope of the task. | 249 // Set up SequenceToken as expected for the scope of the task. |
| 227 ScopedSetSequenceTokenForCurrentThread | 250 ScopedSetSequenceTokenForCurrentThread |
| 228 scoped_set_sequence_token_for_current_thread(sequence_token); | 251 scoped_set_sequence_token_for_current_thread(sequence_token); |
| 229 | 252 |
| 230 // Set up TaskRunnerHandle as expected for the scope of the task. | 253 // Set up TaskRunnerHandle as expected for the scope of the task. |
| 231 std::unique_ptr<SequencedTaskRunnerHandle> sequenced_task_runner_handle; | 254 std::unique_ptr<SequencedTaskRunnerHandle> sequenced_task_runner_handle; |
| 232 std::unique_ptr<ThreadTaskRunnerHandle> single_thread_task_runner_handle; | 255 std::unique_ptr<ThreadTaskRunnerHandle> single_thread_task_runner_handle; |
| 233 DCHECK(!task->sequenced_task_runner_ref || | 256 DCHECK(!task->sequenced_task_runner_ref || |
| 234 !task->single_thread_task_runner_ref); | 257 !task->single_thread_task_runner_ref); |
| 235 if (task->sequenced_task_runner_ref) { | 258 if (task->sequenced_task_runner_ref) { |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 subtle::NoBarrier_AtomicIncrement(&num_pending_undelayed_tasks_, -1); | 458 subtle::NoBarrier_AtomicIncrement(&num_pending_undelayed_tasks_, -1); |
| 436 DCHECK_GE(new_num_pending_undelayed_tasks, 0); | 459 DCHECK_GE(new_num_pending_undelayed_tasks, 0); |
| 437 if (new_num_pending_undelayed_tasks == 0) { | 460 if (new_num_pending_undelayed_tasks == 0) { |
| 438 AutoSchedulerLock auto_lock(flush_lock_); | 461 AutoSchedulerLock auto_lock(flush_lock_); |
| 439 flush_cv_->Signal(); | 462 flush_cv_->Signal(); |
| 440 } | 463 } |
| 441 } | 464 } |
| 442 | 465 |
| 443 } // namespace internal | 466 } // namespace internal |
| 444 } // namespace base | 467 } // namespace base |
| OLD | NEW |