blob: c16325b0781338045a6fcfba17f74eee6f5999ef [file] [log] [blame]
Christopher Wiley2ab1bec2014-04-11 11:04:49 -07001// 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 BUFFET_ASYNC_EVENT_SEQUENCER_H_
6#define BUFFET_ASYNC_EVENT_SEQUENCER_H_
7
8#include <set>
9#include <string>
10#include <vector>
11
12#include <base/bind.h>
13#include <base/basictypes.h>
14#include <base/memory/ref_counted.h>
15
16namespace buffet {
17
18namespace dbus_utils {
19
20// A helper class for coordinating the multiple async tasks. A consumer
21// may grab any number of callbacks via Get*Handler() and schedule a list
Alex Vakulenko33797062014-05-12 15:55:25 -070022// of completion actions to take. When all handlers obtained via Get*Handler()
Christopher Wiley2ab1bec2014-04-11 11:04:49 -070023// have been called, the AsyncEventSequencer will call its CompletionActions.
24//
25// Usage:
26//
27// void Init(const base::Callback<void(bool success)> cb) {
28// scoped_refptr<AsyncEventSequencer> sequencer(
29// new AsyncEventSequencer());
30// one_delegate_needing_init_.Init(sequencer->GetHandler(
31// "my delegate failed to init", false));
32// dbus_init_delegate_.Init(sequencer->GetExportHandler(
33// "org.test.Interface", "ExposedMethodName",
34// "another delegate is flaky", false));
35// sequencer->OnAllTasksCompletedCall({cb});
36// }
37class AsyncEventSequencer : public base::RefCounted<AsyncEventSequencer> {
38 public:
39 typedef base::Callback<void(bool success)> Handler;
40 typedef base::Callback<void (const std::string& interface_name,
41 const std::string& method_name,
42 bool success)> ExportHandler;
43 typedef base::Callback<void(bool all_succeeded)> CompletionAction;
Christopher Wileyadb901d2014-05-07 09:58:45 -070044 typedef base::Callback<void(void)> CompletionTask;
Christopher Wiley2ab1bec2014-04-11 11:04:49 -070045
46 AsyncEventSequencer();
Christopher Wileyadb901d2014-05-07 09:58:45 -070047
Christopher Wiley2ab1bec2014-04-11 11:04:49 -070048 // Get a Finished handler callback. Each callback is "unique" in the sense
49 // that subsequent calls to GetHandler() will create new handlers
50 // which will need to be called before completion actions are run.
51 Handler GetHandler(const std::string& descriptive_message,
52 bool failure_is_fatal);
Christopher Wileyadb901d2014-05-07 09:58:45 -070053
Christopher Wiley2ab1bec2014-04-11 11:04:49 -070054 // Like GetHandler except with a signature tailored to
55 // ExportedObject's ExportMethod callback requirements. Will also assert
56 // that the passed interface/method names from ExportedObject are correct.
57 ExportHandler GetExportHandler(
58 const std::string& interface_name, const std::string& method_name,
59 const std::string& descriptive_message, bool failure_is_fatal);
Christopher Wileyadb901d2014-05-07 09:58:45 -070060
Christopher Wiley2ab1bec2014-04-11 11:04:49 -070061 // Once all handlers obtained via GetHandler have run,
62 // we'll run each CompletionAction, then discard our references.
63 // No more handlers may be obtained after this call.
64 void OnAllTasksCompletedCall(std::vector<CompletionAction> actions);
65
Christopher Wileyadb901d2014-05-07 09:58:45 -070066 // Wrap a CompletionTask with a function that discards the result.
67 // This CompletionTask retains no references to the AsyncEventSequencer.
68 CompletionAction WrapCompletionTask(const CompletionTask& task);
69
Christopher Wiley2ab1bec2014-04-11 11:04:49 -070070 private:
71 // We'll partially bind this function before giving it back via
72 // GetHandler. Note that the returned callbacks have
73 // references to *this, which gives us the neat property that we'll
74 // destroy *this only when all our callbacks have been destroyed.
75 void HandleFinish(int registration_number, const std::string& error_message,
76 bool failure_is_fatal, bool success);
77 // Similar to HandleFinish.
78 void HandleDBusMethodExported(
79 const Handler& finish_handler,
80 const std::string& expected_interface_name,
81 const std::string& expected_method_name,
82 const std::string& actual_interface_name,
83 const std::string& actual_method_name,
84 bool success);
85 void RetireRegistration(int registration_number);
86 void CheckForFailure(bool failure_is_fatal, bool success,
87 const std::string& error_message);
88 void PossiblyRunCompletionActions();
89
Alex Vakulenkoa0424dd2014-06-13 16:10:17 -070090 bool started_{false};
91 int registration_counter_{0};
Christopher Wiley2ab1bec2014-04-11 11:04:49 -070092 std::set<int> outstanding_registrations_;
93 std::vector<CompletionAction> completion_actions_;
Alex Vakulenkoa0424dd2014-06-13 16:10:17 -070094 bool had_failures_{false};
Christopher Wiley2ab1bec2014-04-11 11:04:49 -070095 // Ref counted objects have private destructors.
96 ~AsyncEventSequencer();
97 friend class base::RefCounted<AsyncEventSequencer>;
98 DISALLOW_COPY_AND_ASSIGN(AsyncEventSequencer);
99};
100
101} // namespace dbus_utils
102
103} // namespace buffet
104
105#endif // BUFFET_ASYNC_EVENT_SEQUENCER_H_