You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
4.7 KiB
114 lines
4.7 KiB
// 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 LIBBRILLO_BRILLO_DBUS_ASYNC_EVENT_SEQUENCER_H_
|
|
#define LIBBRILLO_BRILLO_DBUS_ASYNC_EVENT_SEQUENCER_H_
|
|
|
|
#include <set>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <base/callback_forward.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 // LIBBRILLO_BRILLO_DBUS_ASYNC_EVENT_SEQUENCER_H_
|