blob: 53dbc297c1fa076bc583b8f46a3d3f59d2083e84 [file] [log] [blame]
Gary Morainf80ef062012-05-16 14:57:04 -07001// Copyright (c) 2012 The Chromium OS 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.
4
5#include "shill/hook_table.h"
6
7#include <string>
8
9#include <base/bind.h>
10#include <base/callback.h>
11
12#include "shill/error.h"
13#include "shill/event_dispatcher.h"
14
15using base::Bind;
16using base::Closure;
17using base::ConstRef;
18using base::Unretained;
19using std::string;
20
21namespace shill {
22
23const int HookTable::kPollIterations = 10;
24
25HookTable::HookTable(EventDispatcher *event_dispatcher)
26 : event_dispatcher_(event_dispatcher),
27 iteration_counter_(0) {}
28
29void HookTable::Add(const string &name, const base::Closure &start,
30 const base::Callback<bool()> &poll) {
31 hook_table_.insert(
32 HookTableMap::value_type(name, HookCallbacks(start, poll)));
33}
34
35void HookTable::Run(int timeout_seconds,
36 const base::Callback<void(const Error &)> &done) {
37 // Run all the start actions in the hook table.
38 for (HookTableMap::const_iterator it = hook_table_.begin();
39 it != hook_table_.end(); ++it) {
40 it->second.start.Run();
41 }
42
43 // Start polling for completion.
44 iteration_counter_ = 0;
45 PollActions(timeout_seconds, done);
46}
47
48void HookTable::PollActions(int timeout_seconds,
49 const base::Callback<void(const Error &)> &done) {
50 // Call all the poll functions in the hook table.
51 bool all_done = true;
52 for (HookTableMap::const_iterator it = hook_table_.begin();
53 it != hook_table_.end(); ++it) {
54 if (!it->second.poll.Run()) {
55 all_done = false;
56 }
57 }
58
59 if (all_done) {
60 done.Run(Error(Error::kSuccess));
61 return;
62 }
63
64 if (iteration_counter_ >= kPollIterations) {
65 done.Run(Error(Error::kOperationTimeout));
66 return;
67 }
68
69 // Some actions have not yet completed. Queue this function to poll again
70 // later.
71 Closure poll_actions_cb = Bind(&HookTable::PollActions, Unretained(this),
72 timeout_seconds, ConstRef(done));
73 const uint64 delay_ms = (timeout_seconds * 1000) / kPollIterations;
74 event_dispatcher_->PostDelayedTask(poll_actions_cb, delay_ms);
75 iteration_counter_++;
76}
77
78} // namespace shill