Chromium Code Reviews| Index: chromecast/base/alarm_manager.cc |
| diff --git a/chromecast/base/alarm_manager.cc b/chromecast/base/alarm_manager.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..803dd7e8d111a1b2d5ee4ae134177f67f09f1368 |
| --- /dev/null |
| +++ b/chromecast/base/alarm_manager.cc |
| @@ -0,0 +1,85 @@ |
| +// 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 "chromecast/base/alarm_manager.h" |
| + |
| +#include "base/memory/ptr_util.h" |
| +#include "base/threading/thread_task_runner_handle.h" |
| +#include "base/time/default_clock.h" |
| + |
| +#define MAKE_SURE_OWN_THREAD(callback, ...) \ |
| + if (!task_runner_->BelongsToCurrentThread()) { \ |
| + task_runner_->PostTask( \ |
| + FROM_HERE, base::Bind(&AlarmManager::callback, \ |
| + weak_factory_.GetWeakPtr(), ##__VA_ARGS__)); \ |
| + return; \ |
| + } |
| + |
| +namespace chromecast { |
| + |
| +namespace { |
| +// How often to poll the clock. |
| +int kClockPollInterval = 5; |
|
halliwell
2017/02/22 19:09:15
nit: kClockPollIntervalSeconds. Comment probably
ryanchung
2017/02/22 19:39:39
Done. heh
|
| +} // namespace |
| + |
| +AlarmManager::AlarmInfo::AlarmInfo( |
| + const base::Closure& task, |
| + base::Time time, |
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
| + : task_(task), time_(time), task_runner_(task_runner) {} |
| + |
| +AlarmManager::AlarmInfo::~AlarmInfo() {} |
| + |
| +AlarmManager::AlarmManager( |
| + std::unique_ptr<base::Clock> clock, |
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
| + : clock_(std::move(clock)), task_runner_(task_runner), weak_factory_(this) { |
| + if (!task_runner.get()) { |
| + alarm_thread_.reset(new base::Thread("Cast_Alarm_Manager_Thread")); |
|
halliwell
2017/02/22 19:09:15
hmmm ... why do we need to create a thread special
ryanchung
2017/02/22 19:39:39
Should we use the UI thread for this? At initializ
halliwell
2017/02/22 19:42:43
Yep, should be fine ... doesn't look like you're d
ryanchung
2017/02/22 19:51:12
Cool. Done. Using base::ThreadTaskRunnerHandle::Ge
|
| + alarm_thread_->StartWithOptions( |
| + base::Thread::Options(base::MessageLoop::TYPE_DEFAULT, 0)); |
| + task_runner_ = alarm_thread_->task_runner(); |
| + } |
| + clock_tick_timer_.reset(new base::RepeatingTimer()); |
| + clock_tick_timer_->SetTaskRunner(task_runner_); |
| + base::TimeDelta polling_frequency = |
| + base::TimeDelta::FromSeconds(kClockPollInterval); |
| + clock_tick_timer_->Start( |
| + FROM_HERE, polling_frequency, |
| + base::Bind(&AlarmManager::CheckAlarm, weak_factory_.GetWeakPtr())); |
| +} |
| + |
| +AlarmManager::AlarmManager() |
| + : AlarmManager(base::MakeUnique<base::DefaultClock>(), nullptr) {} |
| + |
| +AlarmManager::~AlarmManager() { |
| + clock_tick_timer_.reset(nullptr); |
| +} |
| + |
| +void AlarmManager::PostAlarmTask(const base::Closure& task, base::Time time) { |
| + AddAlarm(task, time, base::ThreadTaskRunnerHandle::Get()); |
| +} |
| + |
| +void AlarmManager::AddAlarm( |
| + const base::Closure& task, |
| + base::Time time, |
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { |
| + MAKE_SURE_OWN_THREAD(AddAlarm, task, time, task_runner); |
| + std::unique_ptr<AlarmInfo> info = |
| + base::MakeUnique<AlarmInfo>(task, time, task_runner); |
| + next_alarm_.push(std::move(info)); |
| +} |
| + |
| +void AlarmManager::CheckAlarm() { |
| + DCHECK(task_runner_->BelongsToCurrentThread()); |
| + base::Time now = clock_->Now(); |
| + // Fire appropriate alarms. |
| + while ((!next_alarm_.empty()) && now >= next_alarm_.top()->time()) { |
| + next_alarm_.top()->task_runner()->PostTask(FROM_HERE, |
| + next_alarm_.top()->task()); |
| + next_alarm_.pop(); |
| + } |
| +} |
| + |
| +} // namespace chromecast |