This source file includes following definitions.
- ScheduleTask
- RunEligibleTasks
- eligible
- MakeTaskWaiting
- MakeTaskEligible
- RunAndDeleteTask
#include "components/domain_reliability/dispatcher.h"
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
#include "base/timer/timer.h"
#include "components/domain_reliability/util.h"
namespace domain_reliability {
DomainReliabilityDispatcher::DomainReliabilityDispatcher(MockableTime* time)
: time_(time) {}
DomainReliabilityDispatcher::~DomainReliabilityDispatcher() {
STLDeleteElements(&tasks_);
}
void DomainReliabilityDispatcher::ScheduleTask(
const base::Closure& closure,
base::TimeDelta min_delay,
base::TimeDelta max_delay) {
DCHECK(!closure.is_null());
DCHECK(min_delay <= max_delay);
Task* task = new Task(closure, time_->CreateTimer(), min_delay, max_delay);
tasks_.insert(task);
if (max_delay.InMicroseconds() < 0)
RunAndDeleteTask(task);
else if (min_delay.InMicroseconds() < 0)
MakeTaskEligible(task);
else
MakeTaskWaiting(task);
}
void DomainReliabilityDispatcher::RunEligibleTasks() {
std::set<Task*> tasks;
tasks.swap(eligible_tasks_);
for (std::set<Task*>::const_iterator it = tasks.begin();
it != tasks.end();
++it) {
Task* task = *it;
DCHECK(task);
DCHECK(task->eligible);
RunAndDeleteTask(task);
}
}
DomainReliabilityDispatcher::Task::Task(const base::Closure& closure,
scoped_ptr<MockableTime::Timer> timer,
base::TimeDelta min_delay,
base::TimeDelta max_delay)
: closure(closure),
timer(timer.Pass()),
min_delay(min_delay),
max_delay(max_delay),
eligible(false) {}
DomainReliabilityDispatcher::Task::~Task() {}
void DomainReliabilityDispatcher::MakeTaskWaiting(Task* task) {
DCHECK(task);
DCHECK(!task->eligible);
DCHECK(!task->timer->IsRunning());
task->timer->Start(
FROM_HERE,
task->min_delay,
base::Bind(
&DomainReliabilityDispatcher::MakeTaskEligible,
base::Unretained(this),
task));
}
void
DomainReliabilityDispatcher::MakeTaskEligible(Task* task) {
DCHECK(task);
DCHECK(!task->eligible);
task->eligible = true;
eligible_tasks_.insert(task);
task->timer->Start(
FROM_HERE,
task->max_delay - task->min_delay,
base::Bind(
&DomainReliabilityDispatcher::RunAndDeleteTask,
base::Unretained(this),
task));
}
void DomainReliabilityDispatcher::RunAndDeleteTask(Task* task) {
DCHECK(task);
DCHECK(!task->closure.is_null());
task->closure.Run();
if (task->eligible)
eligible_tasks_.erase(task);
tasks_.erase(task);
delete task;
}
}