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 17namespace brillo { 18 19namespace 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// } 38class 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