Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Side by Side Diff: services/media/framework/util/incident.h

Issue 2024953003: Motown: Move framework/util/incident* so other services can use it (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium 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 MOJO_SERVICES_MEDIA_FRAMEWORK_UTIL_INCIDENT_H_
6 #define MOJO_SERVICES_MEDIA_FRAMEWORK_UTIL_INCIDENT_H_
7
8 #include <functional>
9 #include <vector>
10
11 #include "base/synchronization/lock.h"
12
13 namespace mojo {
14 namespace media {
15
16 // The Incident class provides a facility for executing code as the consequence
17 // of some occurrence. This can be useful for building state machines and
18 // otherwise dealing with asynchronous operations.
19 //
20 // Incident is not a thread-safe class and has no ability to make a thread wait
21 // or to execute code on a particular thread.
22 //
23 // Incidents rely heavily on std::function, so they shouldn't be used in
24 // enormous numbers.
25 //
26 // An Incident can be in one of two states: initial state or occurred state.
27 //
28 // Code can be executed when an incident occurs:
29 //
30 // incident.When([]() {
31 // // Do something...
32 // });
33 //
34 // The behavior of the When method depends on the incident's state. In initial
35 // state, the consequence is added to a list to be executed when the incident
36 // occurs. In occurred state, When executes the consequence immediately (before
37 // When returns).
38 //
39 // An Incident occurs when its Occur (or Run) method is invoked and the Incident
40 // is in the initial state. All registered consequences of the Incident are
41 // executed during the call to Occur in the order they were added. Subsequent
42 // calls to Occur are ignored until the Incident is reset.
43 //
44 // The Reset method ensures that the Incident is in its initial state and that
45 // the list of consequences is cleared (without running the consequences).
46 class Incident {
47 public:
48 Incident();
49
50 ~Incident();
51
52 // Determines if this Incident has occurred due to a past call to Occur.
53 bool occurred() { return occurred_; }
54
55 // Executes the consequence when this Incident occurs. If this Incident hasn't
56 // occurred when this method is called, a copy of the consequence is held
57 // until this Incident occurs or is reset. If this Incident has occurred when
58 // this method is called, the consequence is executed immediately and no copy
59 // of the consequence is held.
60 void When(const std::function<void()>& consequence) {
61 if (occurred_) {
62 consequence();
63 } else {
64 consequences_.push_back(consequence);
65 }
66 }
67
68 // If this Incident is in inital state (!occurred()), this method makes this
69 // Incident occur, executing and deleting all its consequences. Otherwise,
70 // does nothing.
71 void Occur();
72
73 // Resets this Incident to initial state and clears the list of consequences.
74 void Reset() {
75 occurred_ = false;
76 consequences_.clear();
77 }
78
79 // Calls Occur. This method makes an Incident convertible to
80 // mojo::Callback<void()>.
81 void Run() { Occur(); }
82
83 private:
84 bool occurred_ = false;
85 std::vector<std::function<void()>> consequences_;
86 };
87
88 // Like Incident, but threadsafe.
89 class ThreadsafeIncident {
90 public:
91 ThreadsafeIncident();
92
93 ~ThreadsafeIncident();
94
95 // Determines if this ThreadsafeIncident has occurred due to a past call to
96 // Occur. Note that the state of the this ThreadsafeIncident may change
97 // immediately after this method returns, so there's no guarantee that the
98 // result is still valid.
99 bool occurred() {
100 base::AutoLock lock(consequences_lock_);
101 return occurred_;
102 }
103
104 // Executes the consequence when this ThreadsafeIncident occurs. If this
105 // ThreadsafeIncident hasn't occurred when this method is called, a copy of
106 // the consequence is held until this ThreadsafeIncident occurs or is reset.
107 // If this ThreadsafeIncident has occurred when this method is called, the
108 // consequence is executed immediately and no copy of the consequence is held.
109 // Note that this ThreadsafeIncident's internal lock is not held when the
110 // consequence is called. It's therefore possible for this ThreadsafeIncident
111 // to be reset between the time the decision is made to run the consequence
112 // and when the consequence is actually run.
113 void When(const std::function<void()>& consequence) {
114 {
115 base::AutoLock lock(consequences_lock_);
116 if (!occurred_) {
117 consequences_.push_back(consequence);
118 return;
119 }
120 }
121
122 consequence();
123 }
124
125 // If this ThreadsafeIncident is in inital state (!occurred()), this method
126 // makes this ThreadsafeIncident occur, executing and deleting all its
127 // consequences. Otherwise, does nothing.
128 void Occur();
129
130 // Resets this ThreadsafeIncident to initial state and clears the list of
131 // consequences.
132 void Reset() {
133 base::AutoLock lock(consequences_lock_);
134 occurred_ = false;
135 consequences_.clear();
136 }
137
138 // Calls Occur. This method makes an ThreadsafeIncident convertible to
139 // mojo::Callback<void()>.
140 void Run() { Occur(); }
141
142 private:
143 mutable base::Lock consequences_lock_;
144 bool occurred_ = false;
145 std::vector<std::function<void()>> consequences_;
146 };
147
148 } // namespace media
149 } // namespace mojo
150
151 #endif // MOJO_SERVICES_MEDIA_FRAMEWORK_UTIL_INCIDENT_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698