diff options
Diffstat (limited to 'brillo/dbus/async_event_sequencer.h')
-rw-r--r-- | brillo/dbus/async_event_sequencer.h | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/brillo/dbus/async_event_sequencer.h b/brillo/dbus/async_event_sequencer.h new file mode 100644 index 0000000..719c9ad --- /dev/null +++ b/brillo/dbus/async_event_sequencer.h @@ -0,0 +1,113 @@ +// Copyright 2014 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef LIBCHROMEOS_BRILLO_DBUS_ASYNC_EVENT_SEQUENCER_H_ +#define LIBCHROMEOS_BRILLO_DBUS_ASYNC_EVENT_SEQUENCER_H_ + +#include <set> +#include <string> +#include <vector> + +#include <base/bind.h> +#include <base/macros.h> +#include <base/memory/ref_counted.h> +#include <brillo/brillo_export.h> + +namespace brillo { + +namespace dbus_utils { + +// A helper class for coordinating the multiple async tasks. A consumer +// may grab any number of callbacks via Get*Handler() and schedule a list +// of completion actions to take. When all handlers obtained via Get*Handler() +// have been called, the AsyncEventSequencer will call its CompletionActions. +// +// Usage: +// +// void Init(const base::Callback<void(bool success)> cb) { +// scoped_refptr<AsyncEventSequencer> sequencer( +// new AsyncEventSequencer()); +// one_delegate_needing_init_.Init(sequencer->GetHandler( +// "my delegate failed to init", false)); +// dbus_init_delegate_.Init(sequencer->GetExportHandler( +// "org.test.Interface", "ExposedMethodName", +// "another delegate is flaky", false)); +// sequencer->OnAllTasksCompletedCall({cb}); +// } +class BRILLO_EXPORT AsyncEventSequencer + : public base::RefCounted<AsyncEventSequencer> { + public: + using Handler = base::Callback<void(bool success)>; + using ExportHandler = base::Callback<void(const std::string& interface_name, + const std::string& method_name, + bool success)>; + using CompletionAction = base::Callback<void(bool all_succeeded)>; + using CompletionTask = base::Callback<void(void)>; + + AsyncEventSequencer(); + + // Get a Finished handler callback. Each callback is "unique" in the sense + // that subsequent calls to GetHandler() will create new handlers + // which will need to be called before completion actions are run. + Handler GetHandler(const std::string& descriptive_message, + bool failure_is_fatal); + + // Like GetHandler except with a signature tailored to + // ExportedObject's ExportMethod callback requirements. Will also assert + // that the passed interface/method names from ExportedObject are correct. + ExportHandler GetExportHandler(const std::string& interface_name, + const std::string& method_name, + const std::string& descriptive_message, + bool failure_is_fatal); + + // Once all handlers obtained via GetHandler have run, + // we'll run each CompletionAction, then discard our references. + // No more handlers may be obtained after this call. + void OnAllTasksCompletedCall(std::vector<CompletionAction> actions); + + // Wrap a CompletionTask with a function that discards the result. + // This CompletionTask retains no references to the AsyncEventSequencer. + static CompletionAction WrapCompletionTask(const CompletionTask& task); + // Create a default CompletionAction that doesn't do anything when called. + static CompletionAction GetDefaultCompletionAction(); + + private: + // We'll partially bind this function before giving it back via + // GetHandler. Note that the returned callbacks have + // references to *this, which gives us the neat property that we'll + // destroy *this only when all our callbacks have been destroyed. + BRILLO_PRIVATE void HandleFinish(int registration_number, + const std::string& error_message, + bool failure_is_fatal, + bool success); + // Similar to HandleFinish. + BRILLO_PRIVATE void HandleDBusMethodExported( + const Handler& finish_handler, + const std::string& expected_interface_name, + const std::string& expected_method_name, + const std::string& actual_interface_name, + const std::string& actual_method_name, + bool success); + BRILLO_PRIVATE void RetireRegistration(int registration_number); + BRILLO_PRIVATE void CheckForFailure(bool failure_is_fatal, + bool success, + const std::string& error_message); + BRILLO_PRIVATE void PossiblyRunCompletionActions(); + + bool started_{false}; + int registration_counter_{0}; + std::set<int> outstanding_registrations_; + std::vector<CompletionAction> completion_actions_; + bool had_failures_{false}; + // Ref counted objects have private destructors. + ~AsyncEventSequencer(); + friend class base::RefCounted<AsyncEventSequencer>; + DISALLOW_COPY_AND_ASSIGN(AsyncEventSequencer); +}; + +} // namespace dbus_utils + +} // namespace brillo + +#endif // LIBCHROMEOS_BRILLO_DBUS_ASYNC_EVENT_SEQUENCER_H_ |