blob: b90b5525051efbd12b190c4dab147de4c5e726bb [file] [log] [blame]
Christopher Wiley2ab1bec2014-04-11 11:04:49 -07001// Copyright 2014 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 "buffet/async_event_sequencer.h"
6
7namespace buffet {
8
9namespace dbus_utils {
10
11AsyncEventSequencer::AsyncEventSequencer() { }
12AsyncEventSequencer::~AsyncEventSequencer() { }
13
14AsyncEventSequencer::Handler AsyncEventSequencer::GetHandler(
15 const std::string& descriptive_message, bool failure_is_fatal) {
16 CHECK(!started_) << "Cannot create handlers after OnAllTasksCompletedCall()";
17 int unique_registration_id = ++registration_counter_;
18 outstanding_registrations_.insert(unique_registration_id);
19 return base::Bind(&AsyncEventSequencer::HandleFinish, this,
20 unique_registration_id, descriptive_message,
21 failure_is_fatal);
22}
23
24AsyncEventSequencer::ExportHandler AsyncEventSequencer::GetExportHandler(
25 const std::string& interface_name, const std::string& method_name,
26 const std::string& descriptive_message, bool failure_is_fatal) {
27 auto finish_handler = GetHandler(descriptive_message, failure_is_fatal);
28 return base::Bind(&AsyncEventSequencer::HandleDBusMethodExported, this,
29 finish_handler,
30 interface_name,
31 method_name);
32}
33
34void AsyncEventSequencer::OnAllTasksCompletedCall(
35 std::vector<CompletionAction> actions) {
36 CHECK(!started_) << "OnAllTasksCompletedCall called twice!";
37 started_ = true;
38 completion_actions_.assign(actions.begin(), actions.end());
39 // All of our callbacks might have been called already.
40 PossiblyRunCompletionActions();
41}
42
Christopher Wileyadb901d2014-05-07 09:58:45 -070043namespace {
44void IgnoreSuccess(const AsyncEventSequencer::CompletionTask& task,
45 bool /*success*/) { task.Run(); }
46} // namespace
47
48AsyncEventSequencer::CompletionAction AsyncEventSequencer::WrapCompletionTask(
49 const CompletionTask& task) {
50 return base::Bind(&IgnoreSuccess, task);
51}
52
Christopher Wiley2ab1bec2014-04-11 11:04:49 -070053void AsyncEventSequencer::HandleFinish(int registration_number,
54 const std::string& error_message,
55 bool failure_is_fatal, bool success) {
56 RetireRegistration(registration_number);
57 CheckForFailure(failure_is_fatal, success, error_message);
58 PossiblyRunCompletionActions();
59}
60
61void AsyncEventSequencer::HandleDBusMethodExported(
62 const AsyncEventSequencer::Handler& finish_handler,
63 const std::string& expected_interface_name,
64 const std::string& expected_method_name,
65 const std::string& actual_interface_name,
66 const std::string& actual_method_name, bool success) {
Alex Vakulenko33797062014-05-12 15:55:25 -070067 CHECK_EQ(expected_method_name, actual_method_name)
Christopher Wiley2ab1bec2014-04-11 11:04:49 -070068 << "Exported DBus method '" << actual_method_name << "' "
69 << "but expected '" << expected_method_name << "'";
Alex Vakulenko33797062014-05-12 15:55:25 -070070 CHECK_EQ(expected_interface_name, actual_interface_name)
Christopher Wiley2ab1bec2014-04-11 11:04:49 -070071 << "Exported method DBus interface '" << actual_interface_name << "' "
72 << "but expected '" << expected_interface_name << "'";
73 finish_handler.Run(success);
74}
75
76
77void AsyncEventSequencer::RetireRegistration(int registration_number) {
78 const size_t handlers_retired = outstanding_registrations_.erase(
79 registration_number);
Alex Vakulenko33797062014-05-12 15:55:25 -070080 CHECK_EQ(1, handlers_retired)
Christopher Wiley2ab1bec2014-04-11 11:04:49 -070081 << "Tried to retire invalid handler " << registration_number << ")";
82}
83
84void AsyncEventSequencer::CheckForFailure(bool failure_is_fatal, bool success,
85 const std::string& error_message) {
86 if (failure_is_fatal) {
87 CHECK(success) << error_message;
88 }
89 if (!success) {
90 LOG(ERROR) << error_message;
91 had_failures_ = true;
92 }
93}
94
95void AsyncEventSequencer::PossiblyRunCompletionActions() {
96 if (!started_ || !outstanding_registrations_.empty()) {
97 // Don't run completion actions if we have any outstanding
98 // Handlers outstanding or if any more handlers might
99 // be scheduled in the future.
100 return;
101 }
Alex Vakulenkoa0424dd2014-06-13 16:10:17 -0700102 for (const auto& completion_action : completion_actions_) {
Christopher Wiley2ab1bec2014-04-11 11:04:49 -0700103 // Should this be put on the message loop or run directly?
104 completion_action.Run(!had_failures_);
105 }
106 // Discard our references to those actions.
107 completion_actions_.clear();
108}
109
110} // namespace dbus_utils
111
112} // namespace buffet