blob: 98bd8b642ce2cb53ef46fb5d573d21728074ab56 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/task/task_scheduler/scheduler_worker_pool.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/lazy_instance.h"
#include "base/task/task_scheduler/task_tracker.h"
#include "base/threading/thread_local.h"
namespace base {
namespace internal {
namespace {
// SchedulerWorkerPool that owns the current thread, if any.
LazyInstance<ThreadLocalPointer<const SchedulerWorkerPool>>::Leaky
tls_current_worker_pool = LAZY_INSTANCE_INITIALIZER;
const SchedulerWorkerPool* GetCurrentWorkerPool() {
return tls_current_worker_pool.Get().Get();
}
} // namespace
SchedulerWorkerPool::SchedulerWorkerPool(
TrackedRef<TaskTracker> task_tracker,
TrackedRef<Delegate> delegate)
: task_tracker_(std::move(task_tracker)),
delegate_(std::move(delegate)) {
DCHECK(task_tracker_);
}
SchedulerWorkerPool::~SchedulerWorkerPool() = default;
void SchedulerWorkerPool::BindToCurrentThread() {
DCHECK(!GetCurrentWorkerPool());
tls_current_worker_pool.Get().Set(this);
}
void SchedulerWorkerPool::UnbindFromCurrentThread() {
DCHECK(GetCurrentWorkerPool());
tls_current_worker_pool.Get().Set(nullptr);
}
bool SchedulerWorkerPool::IsBoundToCurrentThread() const {
return GetCurrentWorkerPool() == this;
}
void SchedulerWorkerPool::PostTaskWithSequenceNow(
Task task,
SequenceAndTransaction sequence_and_transaction) {
DCHECK(task.task);
// Confirm that |task| is ready to run (its delayed run time is either null or
// in the past).
DCHECK_LE(task.delayed_run_time, TimeTicks::Now());
const bool sequence_was_empty =
sequence_and_transaction.transaction.PushTask(std::move(task));
if (sequence_was_empty) {
// Try to schedule the Sequence locked by |sequence_transaction| if it was
// empty before |task| was inserted into it. Otherwise, one of these must be
// true:
// - The Sequence is already scheduled, or,
// - The pool is running a Task from the Sequence. The pool is expected to
// reschedule the Sequence once it's done running the Task.
if (task_tracker_->WillScheduleSequence(
sequence_and_transaction.transaction, this)) {
OnCanScheduleSequence(std::move(sequence_and_transaction));
}
}
}
} // namespace internal
} // namespace base