• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 #ifndef LIBBRILLO_BRILLO_DBUS_ASYNC_EVENT_SEQUENCER_H_
6 #define LIBBRILLO_BRILLO_DBUS_ASYNC_EVENT_SEQUENCER_H_
7 
8 #include <set>
9 #include <string>
10 #include <vector>
11 
12 #include <base/bind.h>
13 #include <base/macros.h>
14 #include <base/memory/ref_counted.h>
15 #include <brillo/brillo_export.h>
16 
17 namespace brillo {
18 
19 namespace dbus_utils {
20 
21 // A helper class for coordinating the multiple async tasks.  A consumer
22 // may grab any number of callbacks via Get*Handler() and schedule a list
23 // of completion actions to take.  When all handlers obtained via Get*Handler()
24 // have been called, the AsyncEventSequencer will call its CompletionActions.
25 //
26 // Usage:
27 //
28 // void Init(const base::Callback<void(bool success)> cb) {
29 //   scoped_refptr<AsyncEventSequencer> sequencer(
30 //       new AsyncEventSequencer());
31 //   one_delegate_needing_init_.Init(sequencer->GetHandler(
32 //       "my delegate failed to init", false));
33 //   dbus_init_delegate_.Init(sequencer->GetExportHandler(
34 //       "org.test.Interface", "ExposedMethodName",
35 //       "another delegate is flaky", false));
36 //   sequencer->OnAllTasksCompletedCall({cb});
37 // }
38 class BRILLO_EXPORT AsyncEventSequencer
39     : public base::RefCounted<AsyncEventSequencer> {
40  public:
41   using Handler = base::Callback<void(bool success)>;
42   using ExportHandler = base::Callback<void(const std::string& interface_name,
43                                             const std::string& method_name,
44                                             bool success)>;
45   using CompletionAction = base::Callback<void(bool all_succeeded)>;
46   using CompletionTask = base::Callback<void(void)>;
47 
48   AsyncEventSequencer();
49 
50   // Get a Finished handler callback.  Each callback is "unique" in the sense
51   // that subsequent calls to GetHandler() will create new handlers
52   // which will need to be called before completion actions are run.
53   Handler GetHandler(const std::string& descriptive_message,
54                      bool failure_is_fatal);
55 
56   // Like GetHandler except with a signature tailored to
57   // ExportedObject's ExportMethod callback requirements.  Will also assert
58   // that the passed interface/method names from ExportedObject are correct.
59   ExportHandler GetExportHandler(const std::string& interface_name,
60                                  const std::string& method_name,
61                                  const std::string& descriptive_message,
62                                  bool failure_is_fatal);
63 
64   // Once all handlers obtained via GetHandler have run,
65   // we'll run each CompletionAction, then discard our references.
66   // No more handlers may be obtained after this call.
67   void OnAllTasksCompletedCall(std::vector<CompletionAction> actions);
68 
69   // Wrap a CompletionTask with a function that discards the result.
70   // This CompletionTask retains no references to the AsyncEventSequencer.
71   static CompletionAction WrapCompletionTask(const CompletionTask& task);
72   // Create a default CompletionAction that doesn't do anything when called.
73   static CompletionAction GetDefaultCompletionAction();
74 
75  private:
76   // We'll partially bind this function before giving it back via
77   // GetHandler.  Note that the returned callbacks have
78   // references to *this, which gives us the neat property that we'll
79   // destroy *this only when all our callbacks have been destroyed.
80   BRILLO_PRIVATE void HandleFinish(int registration_number,
81                                    const std::string& error_message,
82                                    bool failure_is_fatal,
83                                    bool success);
84   // Similar to HandleFinish.
85   BRILLO_PRIVATE void HandleDBusMethodExported(
86       const Handler& finish_handler,
87       const std::string& expected_interface_name,
88       const std::string& expected_method_name,
89       const std::string& actual_interface_name,
90       const std::string& actual_method_name,
91       bool success);
92   BRILLO_PRIVATE void RetireRegistration(int registration_number);
93   BRILLO_PRIVATE void CheckForFailure(bool failure_is_fatal,
94                                       bool success,
95                                       const std::string& error_message);
96   BRILLO_PRIVATE void PossiblyRunCompletionActions();
97 
98   bool started_{false};
99   int registration_counter_{0};
100   std::set<int> outstanding_registrations_;
101   std::vector<CompletionAction> completion_actions_;
102   bool had_failures_{false};
103   // Ref counted objects have private destructors.
104   ~AsyncEventSequencer();
105   friend class base::RefCounted<AsyncEventSequencer>;
106   DISALLOW_COPY_AND_ASSIGN(AsyncEventSequencer);
107 };
108 
109 }  // namespace dbus_utils
110 
111 }  // namespace brillo
112 
113 #endif  // LIBBRILLO_BRILLO_DBUS_ASYNC_EVENT_SEQUENCER_H_
114