Home | History | Annotate | Download | only in dbus
      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