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

Unified Diff: base/task_scheduler/delayed_task_manager.cc

Issue 2810873008: Separate the create and start phases in DelayedTaskManager. (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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/task_scheduler/delayed_task_manager.h ('k') | base/task_scheduler/delayed_task_manager_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/task_scheduler/delayed_task_manager.cc
diff --git a/base/task_scheduler/delayed_task_manager.cc b/base/task_scheduler/delayed_task_manager.cc
index 0bf7565a33957ae622b3f29b518df6d5e0be20b8..5cf1895fa44ead11336e3747465d5683d2d1ab0c 100644
--- a/base/task_scheduler/delayed_task_manager.cc
+++ b/base/task_scheduler/delayed_task_manager.cc
@@ -4,7 +4,7 @@
#include "base/task_scheduler/delayed_task_manager.h"
-#include <utility>
+#include <algorithm>
#include "base/bind.h"
#include "base/logging.h"
@@ -14,30 +14,80 @@
namespace base {
namespace internal {
-DelayedTaskManager::DelayedTaskManager(
- scoped_refptr<TaskRunner> service_thread_task_runner)
- : service_thread_task_runner_(std::move(service_thread_task_runner)) {
- DCHECK(service_thread_task_runner_);
+DelayedTaskManager::DelayedTaskManager(std::unique_ptr<TickClock> tick_clock)
+ : tick_clock_(std::move(tick_clock)) {
+ DCHECK(tick_clock_);
}
DelayedTaskManager::~DelayedTaskManager() = default;
+void DelayedTaskManager::Start(
+ scoped_refptr<TaskRunner> service_thread_task_runner) {
+ DCHECK(service_thread_task_runner);
+
+ decltype(tasks_added_before_start_) tasks_added_before_start;
+
+ {
+ AutoSchedulerLock auto_lock(lock_);
+ DCHECK(!service_thread_task_runner_);
+ DCHECK(!started_.IsSet());
+ service_thread_task_runner_ = std::move(service_thread_task_runner);
+ tasks_added_before_start = std::move(tasks_added_before_start_);
+ // |service_thread_task_runner_| must not change after |started_| is set
+ // (cf. comment above |lock_| in header file).
+ started_.Set();
+ }
+
+ const TimeTicks now = tick_clock_->NowTicks();
+ for (auto& task_and_callback : tasks_added_before_start) {
+ const TimeDelta delay =
+ std::max(TimeDelta(), task_and_callback.first->delayed_run_time - now);
+ AddDelayedTaskNow(std::move(task_and_callback.first), delay,
+ std::move(task_and_callback.second));
+ }
+}
+
void DelayedTaskManager::AddDelayedTask(
std::unique_ptr<Task> task,
- const PostTaskNowCallback& post_task_now_callback) {
+ PostTaskNowCallback post_task_now_callback) {
DCHECK(task);
+ const TimeDelta delay = task->delay;
+ DCHECK(!delay.is_zero());
+
// Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167
// for details.
CHECK(task->task);
- const TimeDelta delay = task->delay;
- DCHECK(!delay.is_zero());
+ // If |started_| is set, the DelayedTaskManager is in a stable state and
+ // AddDelayedTaskNow() can be called without synchronization. Otherwise, it is
+ // necessary to acquire |lock_| and recheck.
+ if (started_.IsSet()) {
+ AddDelayedTaskNow(std::move(task), delay,
+ std::move(post_task_now_callback));
+ } else {
+ AutoSchedulerLock auto_lock(lock_);
+ if (started_.IsSet()) {
+ AddDelayedTaskNow(std::move(task), delay,
+ std::move(post_task_now_callback));
+ } else {
+ tasks_added_before_start_.push_back(
+ {std::move(task), std::move(post_task_now_callback)});
+ }
+ }
+}
+void DelayedTaskManager::AddDelayedTaskNow(
+ std::unique_ptr<Task> task,
+ TimeDelta delay,
+ PostTaskNowCallback post_task_now_callback) {
+ DCHECK(task);
+ DCHECK(started_.IsSet());
// TODO(fdoray): Use |task->delayed_run_time| on the service thread
// MessageLoop rather than recomputing it from |delay|.
service_thread_task_runner_->PostDelayedTask(
- FROM_HERE, BindOnce(post_task_now_callback, Passed(std::move(task))),
+ FROM_HERE,
+ BindOnce(std::move(post_task_now_callback), Passed(std::move(task))),
delay);
}
« no previous file with comments | « base/task_scheduler/delayed_task_manager.h ('k') | base/task_scheduler/delayed_task_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698