1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/domain_reliability/dispatcher.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/stl_util.h"
10 #include "base/timer/timer.h"
11 #include "components/domain_reliability/util.h"
13 namespace domain_reliability
{
15 DomainReliabilityDispatcher::DomainReliabilityDispatcher(MockableTime
* time
)
18 DomainReliabilityDispatcher::~DomainReliabilityDispatcher() {
19 // TODO(ttuttle): STLElementDeleter?
20 STLDeleteElements(&tasks_
);
23 void DomainReliabilityDispatcher::ScheduleTask(
24 const base::Closure
& closure
,
25 base::TimeDelta min_delay
,
26 base::TimeDelta max_delay
) {
27 DCHECK(!closure
.is_null());
28 // Would be DCHECK_LE, but you can't << a TimeDelta.
29 DCHECK(min_delay
<= max_delay
);
31 Task
* task
= new Task(closure
, time_
->CreateTimer(), min_delay
, max_delay
);
33 if (max_delay
.InMicroseconds() < 0)
34 RunAndDeleteTask(task
);
35 else if (min_delay
.InMicroseconds() < 0)
36 MakeTaskEligible(task
);
38 MakeTaskWaiting(task
);
41 void DomainReliabilityDispatcher::RunEligibleTasks() {
42 // Move all eligible tasks to a separate set so that eligible_tasks_.erase in
43 // RunAndDeleteTask won't erase elements out from under the iterator. (Also
44 // keeps RunEligibleTasks from running forever if a task adds a new, already-
45 // eligible task that does the same, and so on.)
46 std::set
<Task
*> tasks
;
47 tasks
.swap(eligible_tasks_
);
49 for (std::set
<Task
*>::const_iterator it
= tasks
.begin();
54 DCHECK(task
->eligible
);
55 RunAndDeleteTask(task
);
59 DomainReliabilityDispatcher::Task::Task(const base::Closure
& closure
,
60 scoped_ptr
<MockableTime::Timer
> timer
,
61 base::TimeDelta min_delay
,
62 base::TimeDelta max_delay
)
69 DomainReliabilityDispatcher::Task::~Task() {}
71 void DomainReliabilityDispatcher::MakeTaskWaiting(Task
* task
) {
73 DCHECK(!task
->eligible
);
74 DCHECK(!task
->timer
->IsRunning());
79 &DomainReliabilityDispatcher::MakeTaskEligible
,
80 base::Unretained(this),
85 DomainReliabilityDispatcher::MakeTaskEligible(Task
* task
) {
87 DCHECK(!task
->eligible
);
88 task
->eligible
= true;
89 eligible_tasks_
.insert(task
);
92 task
->max_delay
- task
->min_delay
,
94 &DomainReliabilityDispatcher::RunAndDeleteTask
,
95 base::Unretained(this),
99 void DomainReliabilityDispatcher::RunAndDeleteTask(Task
* task
) {
101 DCHECK(!task
->closure
.is_null());
104 eligible_tasks_
.erase(task
);
109 } // namespace domain_reliability