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

Side by Side Diff: mojo/public/cpp/bindings/binding_set.h

Issue 2324623003: Revert of Mojo C++ Bindings: Additional support for associated binding sets (Closed)
Patch Set: Created 4 years, 3 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
« no previous file with comments | « mojo/public/cpp/bindings/associated_interface_ptr.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_
7 7
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 17 matching lines...) Expand all
28 static RequestType GetProxy(ProxyType* proxy) { 28 static RequestType GetProxy(ProxyType* proxy) {
29 return mojo::GetProxy(proxy); 29 return mojo::GetProxy(proxy);
30 } 30 }
31 }; 31 };
32 32
33 enum class BindingSetDispatchMode { 33 enum class BindingSetDispatchMode {
34 WITHOUT_CONTEXT, 34 WITHOUT_CONTEXT,
35 WITH_CONTEXT, 35 WITH_CONTEXT,
36 }; 36 };
37 37
38 using BindingId = size_t;
39
40 // Use this class to manage a set of bindings, which are automatically destroyed 38 // Use this class to manage a set of bindings, which are automatically destroyed
41 // and removed from the set when the pipe they are bound to is disconnected. 39 // and removed from the set when the pipe they are bound to is disconnected.
42 template <typename Interface, typename BindingType = Binding<Interface>> 40 template <typename Interface, typename BindingType = Binding<Interface>>
43 class BindingSet { 41 class BindingSet {
44 public: 42 public:
45 using PreDispatchCallback = base::Callback<void(void*)>;
46 using Traits = BindingSetTraits<BindingType>; 43 using Traits = BindingSetTraits<BindingType>;
47 using ProxyType = typename Traits::ProxyType; 44 using ProxyType = typename Traits::ProxyType;
48 using RequestType = typename Traits::RequestType; 45 using RequestType = typename Traits::RequestType;
49 46
50 BindingSet() : BindingSet(BindingSetDispatchMode::WITHOUT_CONTEXT) {} 47 BindingSet() : BindingSet(BindingSetDispatchMode::WITHOUT_CONTEXT) {}
51 48
52 // Constructs a new BindingSet operating in |dispatch_mode|. If |WITH_CONTEXT| 49 // Constructs a new BindingSet operating in |dispatch_mode|. If |WITH_CONTEXT|
53 // is used, AddBinding() supports a |context| argument, and dispatch_context() 50 // is used, AddBinding() supports a |context| argument, and dispatch_context()
54 // may be called during message or error dispatch to identify which specific 51 // may be called during message or error dispatch to identify which specific
55 // binding received the message or error. 52 // binding received the message or error.
56 explicit BindingSet(BindingSetDispatchMode dispatch_mode) 53 explicit BindingSet(BindingSetDispatchMode dispatch_mode)
57 : dispatch_mode_(dispatch_mode) {} 54 : dispatch_mode_(dispatch_mode) {}
58 55
59 void set_connection_error_handler(const base::Closure& error_handler) { 56 void set_connection_error_handler(const base::Closure& error_handler) {
60 error_handler_ = error_handler; 57 error_handler_ = error_handler;
61 } 58 }
62 59
63 // Sets a callback to be invoked immediately before dispatching any message or
64 // error received by any of the bindings in the set. This may only be used
65 // if the set was constructed with |BindingSetDispatchMode::WITH_CONTEXT|.
66 // |handler| is passed the context associated with the binding which received
67 // the message or event about to be dispatched.
68 void set_pre_dispatch_handler(const PreDispatchCallback& handler) {
69 DCHECK(SupportsContext());
70 pre_dispatch_handler_ = handler;
71 }
72
73 // Adds a new binding to the set which binds |request| to |impl|. If |context| 60 // Adds a new binding to the set which binds |request| to |impl|. If |context|
74 // is non-null, dispatch_context() will reflect this value during the extent 61 // is non-null, dispatch_context() will reflect this value during the extent
75 // of any message or error dispatch targeting this specific binding. Note that 62 // of any message or error dispatch targeting this specific binding. Note that
76 // |context| may only be non-null if the BindingSet was constructed with 63 // |context| may only be non-null if the BindingSet was constructed with
77 // |BindingSetDispatchMode::WITH_CONTEXT|. 64 // |BindingSetDispatchMode::WITH_CONTEXT|.
78 BindingId AddBinding(Interface* impl, 65 void AddBinding(Interface* impl,
79 RequestType request, 66 RequestType request,
80 void* context = nullptr) { 67 void* context = nullptr) {
81 DCHECK(!context || SupportsContext()); 68 DCHECK(!context || SupportsContext());
82 BindingId id = next_binding_id_++;
83 DCHECK_GE(next_binding_id_, 0u);
84 std::unique_ptr<Entry> entry = 69 std::unique_ptr<Entry> entry =
85 base::MakeUnique<Entry>(impl, std::move(request), this, id, context); 70 base::MakeUnique<Entry>(impl, std::move(request), this, context);
86 bindings_.insert(std::make_pair(id, std::move(entry))); 71 bindings_.insert(std::make_pair(entry.get(), std::move(entry)));
87 return id;
88 }
89
90 // Removes a binding from the set. Note that this is safe to call even if the
91 // binding corresponding to |id| has already been removed.
92 //
93 // Returns |true| if the binding was removed and |false| if it didn't exist.
94 bool RemoveBinding(BindingId id) {
95 auto it = bindings_.find(id);
96 if (it == bindings_.end())
97 return false;
98 bindings_.erase(it);
99 return true;
100 } 72 }
101 73
102 // Returns a proxy bound to one end of a pipe whose other end is bound to 74 // Returns a proxy bound to one end of a pipe whose other end is bound to
103 // |this|. If |id_storage| is not null, |*id_storage| will be set to the ID 75 // |this|.
104 // of the added binding. 76 ProxyType CreateInterfacePtrAndBind(Interface* impl) {
105 ProxyType CreateInterfacePtrAndBind(Interface* impl,
106 BindingId* id_storage = nullptr) {
107 ProxyType proxy; 77 ProxyType proxy;
108 BindingId id = AddBinding(impl, Traits::GetProxy(&proxy)); 78 AddBinding(impl, Traits::GetProxy(&proxy));
109 if (id_storage)
110 *id_storage = id;
111 return proxy; 79 return proxy;
112 } 80 }
113 81
114 void CloseAllBindings() { bindings_.clear(); } 82 void CloseAllBindings() { bindings_.clear(); }
115 83
116 bool empty() const { return bindings_.empty(); } 84 bool empty() const { return bindings_.empty(); }
117 85
118 // Implementations may call this when processing a dispatched message or 86 // Implementations may call this when processing a dispatched message or
119 // error. During the extent of message or error dispatch, this will return the 87 // error. During the extent of message or error dispatch, this will return the
120 // context associated with the specific binding which received the message or 88 // context associated with the specific binding which received the message or
(...skipping 13 matching lines...) Expand all
134 } 102 }
135 103
136 private: 104 private:
137 friend class Entry; 105 friend class Entry;
138 106
139 class Entry { 107 class Entry {
140 public: 108 public:
141 Entry(Interface* impl, 109 Entry(Interface* impl,
142 RequestType request, 110 RequestType request,
143 BindingSet* binding_set, 111 BindingSet* binding_set,
144 BindingId binding_id,
145 void* context) 112 void* context)
146 : binding_(impl, std::move(request)), 113 : binding_(impl, std::move(request)),
147 binding_set_(binding_set), 114 binding_set_(binding_set),
148 binding_id_(binding_id),
149 context_(context) { 115 context_(context) {
150 if (binding_set->SupportsContext()) 116 if (binding_set->SupportsContext())
151 binding_.AddFilter(base::MakeUnique<DispatchFilter>(this)); 117 binding_.AddFilter(base::MakeUnique<DispatchFilter>(this));
152 binding_.set_connection_error_handler(base::Bind( 118 binding_.set_connection_error_handler(base::Bind(
153 &Entry::OnConnectionError, base::Unretained(this))); 119 &Entry::OnConnectionError, base::Unretained(this)));
154 } 120 }
155 121
156 void FlushForTesting() { binding_.FlushForTesting(); } 122 void FlushForTesting() { binding_.FlushForTesting(); }
157 123
158 private: 124 private:
(...skipping 15 matching lines...) Expand all
174 }; 140 };
175 141
176 void WillDispatch() { 142 void WillDispatch() {
177 DCHECK(binding_set_->SupportsContext()); 143 DCHECK(binding_set_->SupportsContext());
178 binding_set_->SetDispatchContext(context_); 144 binding_set_->SetDispatchContext(context_);
179 } 145 }
180 146
181 void OnConnectionError() { 147 void OnConnectionError() {
182 if (binding_set_->SupportsContext()) 148 if (binding_set_->SupportsContext())
183 WillDispatch(); 149 WillDispatch();
184 binding_set_->OnConnectionError(binding_id_); 150 binding_set_->OnConnectionError(this);
185 } 151 }
186 152
187 BindingType binding_; 153 BindingType binding_;
188 BindingSet* const binding_set_; 154 BindingSet* const binding_set_;
189 const BindingId binding_id_;
190 void* const context_; 155 void* const context_;
191 156
192 DISALLOW_COPY_AND_ASSIGN(Entry); 157 DISALLOW_COPY_AND_ASSIGN(Entry);
193 }; 158 };
194 159
195 void SetDispatchContext(void* context) { 160 void SetDispatchContext(void* context) {
196 DCHECK(SupportsContext()); 161 DCHECK(SupportsContext());
197 dispatch_context_ = context; 162 dispatch_context_ = context;
198 if (!pre_dispatch_handler_.is_null())
199 pre_dispatch_handler_.Run(context);
200 } 163 }
201 164
202 bool SupportsContext() const { 165 bool SupportsContext() const {
203 return dispatch_mode_ == BindingSetDispatchMode::WITH_CONTEXT; 166 return dispatch_mode_ == BindingSetDispatchMode::WITH_CONTEXT;
204 } 167 }
205 168
206 void OnConnectionError(BindingId id) { 169 void OnConnectionError(Entry* entry) {
207 auto it = bindings_.find(id); 170 auto it = bindings_.find(entry);
208 DCHECK(it != bindings_.end()); 171 DCHECK(it != bindings_.end());
209 bindings_.erase(it); 172 bindings_.erase(it);
210 173
211 if (!error_handler_.is_null()) 174 if (!error_handler_.is_null())
212 error_handler_.Run(); 175 error_handler_.Run();
213 } 176 }
214 177
215 BindingSetDispatchMode dispatch_mode_; 178 BindingSetDispatchMode dispatch_mode_;
216 base::Closure error_handler_; 179 base::Closure error_handler_;
217 PreDispatchCallback pre_dispatch_handler_; 180 std::map<Entry*, std::unique_ptr<Entry>> bindings_;
218 BindingId next_binding_id_ = 0;
219 std::map<BindingId, std::unique_ptr<Entry>> bindings_;
220 void* dispatch_context_ = nullptr; 181 void* dispatch_context_ = nullptr;
221 182
222 DISALLOW_COPY_AND_ASSIGN(BindingSet); 183 DISALLOW_COPY_AND_ASSIGN(BindingSet);
223 }; 184 };
224 185
225 } // namespace mojo 186 } // namespace mojo
226 187
227 #endif // MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ 188 #endif // MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/associated_interface_ptr.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698