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

Unified Diff: base/task_scheduler/task_tracker.cc

Issue 2362253002: TaskScheduler: Add FlushForTesting(). (Closed)
Patch Set: fix build error Created 4 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/task_scheduler/task_tracker.h ('k') | base/task_scheduler/task_tracker_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/task_scheduler/task_tracker.cc
diff --git a/base/task_scheduler/task_tracker.cc b/base/task_scheduler/task_tracker.cc
index ea5397049de7b1b350fbb7f9fd41841865a63d83..1d28f2dab0ba95d944a0679641f96d97cc04a635 100644
--- a/base/task_scheduler/task_tracker.cc
+++ b/base/task_scheduler/task_tracker.cc
@@ -6,12 +6,12 @@
#include <limits>
-#include "base/atomicops.h"
#include "base/callback.h"
#include "base/debug/task_annotator.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/sequence_token.h"
+#include "base/synchronization/condition_variable.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -128,10 +128,108 @@ class TaskTracker::State {
DISALLOW_COPY_AND_ASSIGN(State);
};
-TaskTracker::TaskTracker() : state_(new State) {}
+TaskTracker::TaskTracker()
+ : state_(new State),
+ flush_cv_(flush_lock_.CreateConditionVariable()),
+ shutdown_lock_(&flush_lock_) {}
TaskTracker::~TaskTracker() = default;
void TaskTracker::Shutdown() {
+ PerformShutdown();
+ DCHECK(IsShutdownComplete());
+
+ // Unblock Flush() when shutdown completes.
+ AutoSchedulerLock auto_lock(flush_lock_);
+ flush_cv_->Signal();
+}
+
+void TaskTracker::Flush() {
+ AutoSchedulerLock auto_lock(flush_lock_);
+ while (subtle::NoBarrier_Load(&num_pending_undelayed_tasks_) != 0 &&
+ !IsShutdownComplete()) {
+ flush_cv_->Wait();
+ }
+}
+
+bool TaskTracker::WillPostTask(const Task* task) {
+ DCHECK(task);
+
+ if (!BeforePostTask(task->traits.shutdown_behavior()))
+ return false;
+
+ if (task->delayed_run_time.is_null())
+ subtle::NoBarrier_AtomicIncrement(&num_pending_undelayed_tasks_, 1);
+
+ debug::TaskAnnotator task_annotator;
+ task_annotator.DidQueueTask(kQueueFunctionName, *task);
+
+ return true;
+}
+
+bool TaskTracker::RunTask(const Task* task,
+ const SequenceToken& sequence_token) {
+ DCHECK(task);
+ DCHECK(sequence_token.IsValid());
+
+ const TaskShutdownBehavior shutdown_behavior =
+ task->traits.shutdown_behavior();
+ const bool can_run_task = BeforeRunTask(shutdown_behavior);
+
+ if (can_run_task) {
+ // All tasks run through here and the scheduler itself doesn't use
+ // singletons. Therefore, it isn't necessary to reset the singleton allowed
+ // bit after running the task.
+ ThreadRestrictions::SetSingletonAllowed(
+ task->traits.shutdown_behavior() !=
+ TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN);
+
+ {
+ // Set up SequenceToken as expected for the scope of the task.
+ ScopedSetSequenceTokenForCurrentThread
+ scoped_set_sequence_token_for_current_thread(sequence_token);
+
+ // Set up TaskRunnerHandle as expected for the scope of the task.
+ std::unique_ptr<SequencedTaskRunnerHandle> sequenced_task_runner_handle;
+ std::unique_ptr<ThreadTaskRunnerHandle> single_thread_task_runner_handle;
+ DCHECK(!task->sequenced_task_runner_ref ||
+ !task->single_thread_task_runner_ref);
+ if (task->sequenced_task_runner_ref) {
+ sequenced_task_runner_handle.reset(
+ new SequencedTaskRunnerHandle(task->sequenced_task_runner_ref));
+ } else if (task->single_thread_task_runner_ref) {
+ single_thread_task_runner_handle.reset(
+ new ThreadTaskRunnerHandle(task->single_thread_task_runner_ref));
+ }
+
+ TRACE_TASK_EXECUTION(kRunFunctionName, *task);
+
+ debug::TaskAnnotator task_annotator;
+ task_annotator.RunTask(kQueueFunctionName, *task);
+ }
+
+ AfterRunTask(shutdown_behavior);
+ }
+
+ if (task->delayed_run_time.is_null())
+ DecrementNumPendingUndelayedTasks();
+
+ return can_run_task;
+}
+
+bool TaskTracker::HasShutdownStarted() const {
+ return state_->HasShutdownStarted();
+}
+
+bool TaskTracker::IsShutdownComplete() const {
+ AutoSchedulerLock auto_lock(shutdown_lock_);
+ return shutdown_event_ && shutdown_event_->IsSignaled();
+}
+
+void TaskTracker::SetHasShutdownStartedForTesting() {
+ state_->StartShutdown();
+}
+
+void TaskTracker::PerformShutdown() {
{
AutoSchedulerLock auto_lock(shutdown_lock_);
@@ -182,77 +280,6 @@ void TaskTracker::Shutdown() {
}
}
-bool TaskTracker::WillPostTask(const Task* task) {
- DCHECK(task);
-
- if (!BeforePostTask(task->traits.shutdown_behavior()))
- return false;
-
- debug::TaskAnnotator task_annotator;
- task_annotator.DidQueueTask(kQueueFunctionName, *task);
-
- return true;
-}
-
-bool TaskTracker::RunTask(const Task* task,
- const SequenceToken& sequence_token) {
- DCHECK(task);
- DCHECK(sequence_token.IsValid());
-
- const TaskShutdownBehavior shutdown_behavior =
- task->traits.shutdown_behavior();
- if (!BeforeRunTask(shutdown_behavior))
- return false;
-
- // All tasks run through here and the scheduler itself doesn't use singletons.
- // Therefore, it isn't necessary to reset the singleton allowed bit after
- // running the task.
- ThreadRestrictions::SetSingletonAllowed(
- task->traits.shutdown_behavior() !=
- TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN);
-
- {
- // Set up SequenceToken as expected for the scope of the task.
- ScopedSetSequenceTokenForCurrentThread
- scoped_set_sequence_token_for_current_thread(sequence_token);
-
- // Set up TaskRunnerHandle as expected for the scope of the task.
- std::unique_ptr<SequencedTaskRunnerHandle> sequenced_task_runner_handle;
- std::unique_ptr<ThreadTaskRunnerHandle> single_thread_task_runner_handle;
- DCHECK(!task->sequenced_task_runner_ref ||
- !task->single_thread_task_runner_ref);
- if (task->sequenced_task_runner_ref) {
- sequenced_task_runner_handle.reset(
- new SequencedTaskRunnerHandle(task->sequenced_task_runner_ref));
- } else if (task->single_thread_task_runner_ref) {
- single_thread_task_runner_handle.reset(
- new ThreadTaskRunnerHandle(task->single_thread_task_runner_ref));
- }
-
- TRACE_TASK_EXECUTION(kRunFunctionName, *task);
-
- debug::TaskAnnotator task_annotator;
- task_annotator.RunTask(kQueueFunctionName, *task);
- }
-
- AfterRunTask(shutdown_behavior);
-
- return true;
-}
-
-bool TaskTracker::HasShutdownStarted() const {
- return state_->HasShutdownStarted();
-}
-
-bool TaskTracker::IsShutdownComplete() const {
- AutoSchedulerLock auto_lock(shutdown_lock_);
- return shutdown_event_ && shutdown_event_->IsSignaled();
-}
-
-void TaskTracker::SetHasShutdownStartedForTesting() {
- state_->StartShutdown();
-}
-
bool TaskTracker::BeforePostTask(TaskShutdownBehavior shutdown_behavior) {
if (shutdown_behavior == TaskShutdownBehavior::BLOCK_SHUTDOWN) {
// BLOCK_SHUTDOWN tasks block shutdown between the moment they are posted
@@ -352,5 +379,15 @@ void TaskTracker::OnBlockingShutdownTasksComplete() {
shutdown_event_->Signal();
}
+void TaskTracker::DecrementNumPendingUndelayedTasks() {
+ const auto new_num_pending_undelayed_tasks =
+ subtle::NoBarrier_AtomicIncrement(&num_pending_undelayed_tasks_, -1);
+ DCHECK_GE(new_num_pending_undelayed_tasks, 0);
+ if (new_num_pending_undelayed_tasks == 0) {
+ AutoSchedulerLock auto_lock(flush_lock_);
+ flush_cv_->Signal();
+ }
+}
+
} // namespace internal
} // namespace base
« no previous file with comments | « base/task_scheduler/task_tracker.h ('k') | base/task_scheduler/task_tracker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698