blob: 562e5c9058a9551cc615e578f137b34f767a9be7 [file] [log] [blame]
// Copyright 2016 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_scheduler/scheduler_service_thread.h"
#include <utility>
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/synchronization/waitable_event.h"
#include "base/task_scheduler/delayed_task_manager.h"
#include "base/task_scheduler/scheduler_worker.h"
#include "base/task_scheduler/sequence.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
namespace base {
namespace internal {
namespace {
class ServiceThreadDelegate : public SchedulerWorker::Delegate {
public:
ServiceThreadDelegate(DelayedTaskManager* delayed_task_manager)
: delayed_task_manager_(delayed_task_manager) {}
// SchedulerWorker::Delegate:
void OnMainEntry(SchedulerWorker* worker) override {}
scoped_refptr<Sequence> GetWork(SchedulerWorker* worker) override {
delayed_task_manager_->PostReadyTasks();
return nullptr;
}
void ReEnqueueSequence(scoped_refptr<Sequence> sequence) override {
NOTREACHED() <<
"GetWork() never returns a sequence so there's nothing to reenqueue.";
}
TimeDelta GetSleepTimeout() override {
const TimeTicks next_time = delayed_task_manager_->GetDelayedRunTime();
if (next_time.is_null())
return TimeDelta::Max();
// For delayed tasks with delays that are really close to each other, it is
// possible for the current time to advance beyond the required
// GetDelayedWaitTime. Return a minimum of TimeDelta() in the event that
// happens.
TimeDelta sleep_time = next_time - delayed_task_manager_->Now();
const TimeDelta zero_delta;
return sleep_time < zero_delta ? zero_delta : sleep_time;
}
bool CanDetach(SchedulerWorker* worker) override {
return false;
}
private:
DelayedTaskManager* const delayed_task_manager_;
DISALLOW_COPY_AND_ASSIGN(ServiceThreadDelegate);
};
} // namespace
SchedulerServiceThread::~SchedulerServiceThread() = default;
// static
std::unique_ptr<SchedulerServiceThread> SchedulerServiceThread::Create(
TaskTracker* task_tracker, DelayedTaskManager* delayed_task_manager) {
std::unique_ptr<SchedulerWorker> worker =
SchedulerWorker::Create(
ThreadPriority::NORMAL,
WrapUnique(new ServiceThreadDelegate(delayed_task_manager)),
task_tracker,
SchedulerWorker::InitialState::ALIVE);
if (!worker)
return nullptr;
return WrapUnique(new SchedulerServiceThread(std::move(worker)));
}
void SchedulerServiceThread::WakeUp() {
worker_->WakeUp();
}
void SchedulerServiceThread::JoinForTesting() {
worker_->JoinForTesting();
}
SchedulerServiceThread::SchedulerServiceThread(
std::unique_ptr<SchedulerWorker> worker) : worker_(std::move(worker)) {}
} // namespace internal
} // namespace base