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