libchromeos: Migrate AsyncEventSequencer to libchromeos
This enables sharing this functionality between peerd and buffet.
BUG=chromium:398626
TEST=libchromeos/buffet unittests
Change-Id: Ic38b9bbf491b57d18b0409f0587efedeab6ef988
Reviewed-on: https://chromium-review.googlesource.com/210402
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/buffet/async_event_sequencer.cc b/buffet/async_event_sequencer.cc
deleted file mode 100644
index b90b552..0000000
--- a/buffet/async_event_sequencer.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// 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.
-
-#include "buffet/async_event_sequencer.h"
-
-namespace buffet {
-
-namespace dbus_utils {
-
-AsyncEventSequencer::AsyncEventSequencer() { }
-AsyncEventSequencer::~AsyncEventSequencer() { }
-
-AsyncEventSequencer::Handler AsyncEventSequencer::GetHandler(
- const std::string& descriptive_message, bool failure_is_fatal) {
- CHECK(!started_) << "Cannot create handlers after OnAllTasksCompletedCall()";
- int unique_registration_id = ++registration_counter_;
- outstanding_registrations_.insert(unique_registration_id);
- return base::Bind(&AsyncEventSequencer::HandleFinish, this,
- unique_registration_id, descriptive_message,
- failure_is_fatal);
-}
-
-AsyncEventSequencer::ExportHandler AsyncEventSequencer::GetExportHandler(
- const std::string& interface_name, const std::string& method_name,
- const std::string& descriptive_message, bool failure_is_fatal) {
- auto finish_handler = GetHandler(descriptive_message, failure_is_fatal);
- return base::Bind(&AsyncEventSequencer::HandleDBusMethodExported, this,
- finish_handler,
- interface_name,
- method_name);
-}
-
-void AsyncEventSequencer::OnAllTasksCompletedCall(
- std::vector<CompletionAction> actions) {
- CHECK(!started_) << "OnAllTasksCompletedCall called twice!";
- started_ = true;
- completion_actions_.assign(actions.begin(), actions.end());
- // All of our callbacks might have been called already.
- PossiblyRunCompletionActions();
-}
-
-namespace {
-void IgnoreSuccess(const AsyncEventSequencer::CompletionTask& task,
- bool /*success*/) { task.Run(); }
-} // namespace
-
-AsyncEventSequencer::CompletionAction AsyncEventSequencer::WrapCompletionTask(
- const CompletionTask& task) {
- return base::Bind(&IgnoreSuccess, task);
-}
-
-void AsyncEventSequencer::HandleFinish(int registration_number,
- const std::string& error_message,
- bool failure_is_fatal, bool success) {
- RetireRegistration(registration_number);
- CheckForFailure(failure_is_fatal, success, error_message);
- PossiblyRunCompletionActions();
-}
-
-void AsyncEventSequencer::HandleDBusMethodExported(
- const AsyncEventSequencer::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) {
- CHECK_EQ(expected_method_name, actual_method_name)
- << "Exported DBus method '" << actual_method_name << "' "
- << "but expected '" << expected_method_name << "'";
- CHECK_EQ(expected_interface_name, actual_interface_name)
- << "Exported method DBus interface '" << actual_interface_name << "' "
- << "but expected '" << expected_interface_name << "'";
- finish_handler.Run(success);
-}
-
-
-void AsyncEventSequencer::RetireRegistration(int registration_number) {
- const size_t handlers_retired = outstanding_registrations_.erase(
- registration_number);
- CHECK_EQ(1, handlers_retired)
- << "Tried to retire invalid handler " << registration_number << ")";
-}
-
-void AsyncEventSequencer::CheckForFailure(bool failure_is_fatal, bool success,
- const std::string& error_message) {
- if (failure_is_fatal) {
- CHECK(success) << error_message;
- }
- if (!success) {
- LOG(ERROR) << error_message;
- had_failures_ = true;
- }
-}
-
-void AsyncEventSequencer::PossiblyRunCompletionActions() {
- if (!started_ || !outstanding_registrations_.empty()) {
- // Don't run completion actions if we have any outstanding
- // Handlers outstanding or if any more handlers might
- // be scheduled in the future.
- return;
- }
- for (const auto& completion_action : completion_actions_) {
- // Should this be put on the message loop or run directly?
- completion_action.Run(!had_failures_);
- }
- // Discard our references to those actions.
- completion_actions_.clear();
-}
-
-} // namespace dbus_utils
-
-} // namespace buffet
diff --git a/buffet/async_event_sequencer.h b/buffet/async_event_sequencer.h
deleted file mode 100644
index c16325b..0000000
--- a/buffet/async_event_sequencer.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// 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 BUFFET_ASYNC_EVENT_SEQUENCER_H_
-#define BUFFET_ASYNC_EVENT_SEQUENCER_H_
-
-#include <set>
-#include <string>
-#include <vector>
-
-#include <base/bind.h>
-#include <base/basictypes.h>
-#include <base/memory/ref_counted.h>
-
-namespace buffet {
-
-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 AsyncEventSequencer : public base::RefCounted<AsyncEventSequencer> {
- public:
- typedef base::Callback<void(bool success)> Handler;
- typedef base::Callback<void (const std::string& interface_name,
- const std::string& method_name,
- bool success)> ExportHandler;
- typedef base::Callback<void(bool all_succeeded)> CompletionAction;
- typedef base::Callback<void(void)> CompletionTask;
-
- 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.
- CompletionAction WrapCompletionTask(const CompletionTask& task);
-
- 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.
- void HandleFinish(int registration_number, const std::string& error_message,
- bool failure_is_fatal, bool success);
- // Similar to HandleFinish.
- 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);
- void RetireRegistration(int registration_number);
- void CheckForFailure(bool failure_is_fatal, bool success,
- const std::string& error_message);
- 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 buffet
-
-#endif // BUFFET_ASYNC_EVENT_SEQUENCER_H_
diff --git a/buffet/async_event_sequencer_unittest.cc b/buffet/async_event_sequencer_unittest.cc
deleted file mode 100644
index d95ff56..0000000
--- a/buffet/async_event_sequencer_unittest.cc
+++ /dev/null
@@ -1,96 +0,0 @@
-// 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.
-
-#include "buffet/async_event_sequencer.h"
-
-#include <base/bind_helpers.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-namespace buffet {
-
-namespace dbus_utils {
-
-namespace {
-
-const char kTestInterface[] = "org.test.if";
-const char kTestMethod1[] = "TestMethod1";
-const char kTestMethod2[] = "TestMethod2";
-
-} // namespace
-
-class AsyncEventSequencerTest : public ::testing::Test {
- public:
- MOCK_METHOD1(HandleCompletion, void(bool all_succeeded));
-
- void SetUp() {
- aec_ = new AsyncEventSequencer();
- cb_ = base::Bind(&AsyncEventSequencerTest::HandleCompletion,
- base::Unretained(this));
- }
-
- scoped_refptr<AsyncEventSequencer> aec_;
- AsyncEventSequencer::CompletionAction cb_;
-};
-
-TEST_F(AsyncEventSequencerTest, WaitForCompletionActions) {
- auto finished_handler = aec_->GetHandler("handler failed", false);
- finished_handler.Run(true);
- EXPECT_CALL(*this, HandleCompletion(true)).Times(1);
- aec_->OnAllTasksCompletedCall({cb_});
-}
-
-TEST_F(AsyncEventSequencerTest, MultiInitActionsSucceed) {
- auto finished_handler1 = aec_->GetHandler("handler failed", false);
- auto finished_handler2 = aec_->GetHandler("handler failed", false);
- aec_->OnAllTasksCompletedCall({cb_});
- finished_handler1.Run(true);
- EXPECT_CALL(*this, HandleCompletion(true)).Times(1);
- finished_handler2.Run(true);
-}
-
-TEST_F(AsyncEventSequencerTest, SomeInitActionsFail) {
- auto finished_handler1 = aec_->GetHandler("handler failed", false);
- auto finished_handler2 = aec_->GetHandler("handler failed", false);
- aec_->OnAllTasksCompletedCall({cb_});
- finished_handler1.Run(false);
- EXPECT_CALL(*this, HandleCompletion(false)).Times(1);
- finished_handler2.Run(true);
-}
-
-TEST_F(AsyncEventSequencerTest, MultiDBusActionsSucceed) {
- auto handler1 = aec_->GetExportHandler(
- kTestInterface, kTestMethod1, "method export failed", false);
- auto handler2 = aec_->GetExportHandler(
- kTestInterface, kTestMethod2, "method export failed", false);
- aec_->OnAllTasksCompletedCall({cb_});
- handler1.Run(kTestInterface, kTestMethod1, true);
- EXPECT_CALL(*this, HandleCompletion(true)).Times(1);
- handler2.Run(kTestInterface, kTestMethod2, true);
-}
-
-TEST_F(AsyncEventSequencerTest, SomeDBusActionsFail) {
- auto handler1 = aec_->GetExportHandler(
- kTestInterface, kTestMethod1, "method export failed", false);
- auto handler2 = aec_->GetExportHandler(
- kTestInterface, kTestMethod2, "method export failed", false);
- aec_->OnAllTasksCompletedCall({cb_});
- handler1.Run(kTestInterface, kTestMethod1, true);
- EXPECT_CALL(*this, HandleCompletion(false)).Times(1);
- handler2.Run(kTestInterface, kTestMethod2, false);
-}
-
-TEST_F(AsyncEventSequencerTest, MixedActions) {
- auto handler1 = aec_->GetExportHandler(
- kTestInterface, kTestMethod1, "method export failed", false);
- auto handler2 = aec_->GetHandler("handler failed", false);
- aec_->OnAllTasksCompletedCall({cb_});
- handler1.Run(kTestInterface, kTestMethod1, true);
- EXPECT_CALL(*this, HandleCompletion(true)).Times(1);
- handler2.Run(true);
-}
-
-} // namespace dbus_utils
-
-} // namespace buffet
diff --git a/buffet/buffet.gyp b/buffet/buffet.gyp
index 001d610..a9300c4 100644
--- a/buffet/buffet.gyp
+++ b/buffet/buffet.gyp
@@ -5,6 +5,7 @@
'dbus-1',
'libchrome-<(libbase_ver)',
'libchrome-test-<(libbase_ver)',
+ 'libchromeos-<(libbase_ver)',
'libcurl',
'libmetrics-<(libbase_ver)',
],
@@ -24,7 +25,6 @@
'type': 'static_library',
'sources': [
'any.cc',
- 'async_event_sequencer.cc',
'commands/command_definition.cc',
'commands/command_dictionary.cc',
'commands/command_manager.cc',
@@ -84,7 +84,6 @@
'sources': [
'any_unittest.cc',
'any_internal_impl_unittest.cc',
- 'async_event_sequencer_unittest.cc',
'buffet_testrunner.cc',
'commands/command_definition_unittest.cc',
'commands/command_dictionary_unittest.cc',
diff --git a/buffet/exported_object_manager.cc b/buffet/exported_object_manager.cc
index c1403ad..d76e067 100644
--- a/buffet/exported_object_manager.cc
+++ b/buffet/exported_object_manager.cc
@@ -4,9 +4,11 @@
#include "buffet/exported_object_manager.h"
+#include <chromeos/async_event_sequencer.h>
#include <dbus/object_manager.h>
-#include "buffet/async_event_sequencer.h"
+
+using chromeos::dbus_utils::AsyncEventSequencer;
namespace buffet {
@@ -18,8 +20,7 @@
void ExportedObjectManager::Init(const OnInitFinish& cb) {
bus_->AssertOnOriginThread();
- scoped_refptr<dbus_utils::AsyncEventSequencer> sequencer(
- new dbus_utils::AsyncEventSequencer());
+ scoped_refptr<AsyncEventSequencer> sequencer(new AsyncEventSequencer());
exported_object_->ExportMethod(
dbus::kObjectManagerInterface,
dbus::kObjectManagerGetManagedObjects,
diff --git a/buffet/exported_property_set.cc b/buffet/exported_property_set.cc
index b1b5633..3ab3c2d 100644
--- a/buffet/exported_property_set.cc
+++ b/buffet/exported_property_set.cc
@@ -5,12 +5,14 @@
#include "buffet/exported_property_set.h"
#include <base/bind.h>
+#include <chromeos/async_event_sequencer.h>
#include <dbus/bus.h> // For kPropertyInterface
#include <dbus/property.h> // For kPropertyInterface
-#include "buffet/async_event_sequencer.h"
#include "buffet/dbus_utils.h"
+using chromeos::dbus_utils::AsyncEventSequencer;
+
namespace buffet {
namespace dbus_utils {
diff --git a/buffet/main.cc b/buffet/main.cc
index 358358e..eb25d13 100644
--- a/buffet/main.cc
+++ b/buffet/main.cc
@@ -12,15 +12,15 @@
#include <base/message_loop/message_loop.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
+#include <chromeos/async_event_sequencer.h>
#include <dbus/bus.h>
#include <sysexits.h>
-#include "buffet/async_event_sequencer.h"
#include "buffet/dbus_constants.h"
#include "buffet/exported_object_manager.h"
#include "buffet/manager.h"
-using buffet::dbus_utils::AsyncEventSequencer;
+using chromeos::dbus_utils::AsyncEventSequencer;
using buffet::dbus_utils::ExportedObjectManager;
namespace {
diff --git a/buffet/manager.cc b/buffet/manager.cc
index aa29552..0a6af31 100644
--- a/buffet/manager.cc
+++ b/buffet/manager.cc
@@ -10,18 +10,18 @@
#include <base/bind.h>
#include <base/bind_helpers.h>
#include <base/json/json_writer.h>
+#include <chromeos/async_event_sequencer.h>
#include <dbus/bus.h>
#include <dbus/object_path.h>
#include <dbus/values_util.h>
-#include "buffet/async_event_sequencer.h"
#include "buffet/commands/command_manager.h"
#include "buffet/dbus_constants.h"
#include "buffet/dbus_utils.h"
#include "buffet/error.h"
#include "buffet/exported_object_manager.h"
-using buffet::dbus_utils::AsyncEventSequencer;
+using chromeos::dbus_utils::AsyncEventSequencer;
using buffet::dbus_utils::GetBadArgsError;
using buffet::dbus_utils::GetDBusError;