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