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

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

Issue 2692413002: Implements mojo::StrongBindingSet. (Closed)
Patch Set: Created 3 years, 10 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
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 <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/callback.h" 12 #include "base/callback.h"
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/memory/ptr_util.h" 14 #include "base/memory/ptr_util.h"
15 #include "mojo/public/cpp/bindings/binding.h" 15 #include "mojo/public/cpp/bindings/binding.h"
16 #include "mojo/public/cpp/bindings/connection_error_callback.h" 16 #include "mojo/public/cpp/bindings/connection_error_callback.h"
17 #include "mojo/public/cpp/bindings/interface_ptr.h" 17 #include "mojo/public/cpp/bindings/interface_ptr.h"
18 #include "mojo/public/cpp/bindings/interface_request.h" 18 #include "mojo/public/cpp/bindings/interface_request.h"
19 #include "mojo/public/cpp/bindings/message.h" 19 #include "mojo/public/cpp/bindings/message.h"
20 20
21 namespace mojo { 21 namespace mojo {
22 22
23 template <typename BindingType> 23 template <typename BindingType>
24 struct BindingSetTraits; 24 struct BindingSetTraits;
25 25
26 template <typename Interface> 26 template <typename Interface, typename ImplRefTraits>
27 struct BindingSetTraits<Binding<Interface>> { 27 struct BindingSetTraits<Binding<Interface, ImplRefTraits>> {
28 using ProxyType = InterfacePtr<Interface>; 28 using ProxyType = InterfacePtr<Interface>;
29 using RequestType = InterfaceRequest<Interface>; 29 using RequestType = InterfaceRequest<Interface>;
30 using BindingType = Binding<Interface, ImplRefTraits>;
31 using ImplPointerType = typename BindingType::ImplPointerType;
30 32
31 static RequestType MakeRequest(ProxyType* proxy) { 33 static RequestType MakeRequest(ProxyType* proxy) {
32 return mojo::MakeRequest(proxy); 34 return mojo::MakeRequest(proxy);
33 } 35 }
34 }; 36 };
35 37
36 using BindingId = size_t; 38 using BindingId = size_t;
37 39
38 template <typename ContextType> 40 template <typename ContextType>
39 struct BindingSetContextTraits { 41 struct BindingSetContextTraits {
(...skipping 20 matching lines...) Expand all
60 // the extent of any message dispatch targeting that specific binding. 62 // the extent of any message dispatch targeting that specific binding.
61 template <typename Interface, typename BindingType, typename ContextType> 63 template <typename Interface, typename BindingType, typename ContextType>
62 class BindingSetBase { 64 class BindingSetBase {
63 public: 65 public:
64 using ContextTraits = BindingSetContextTraits<ContextType>; 66 using ContextTraits = BindingSetContextTraits<ContextType>;
65 using Context = typename ContextTraits::Type; 67 using Context = typename ContextTraits::Type;
66 using PreDispatchCallback = base::Callback<void(const Context&)>; 68 using PreDispatchCallback = base::Callback<void(const Context&)>;
67 using Traits = BindingSetTraits<BindingType>; 69 using Traits = BindingSetTraits<BindingType>;
68 using ProxyType = typename Traits::ProxyType; 70 using ProxyType = typename Traits::ProxyType;
69 using RequestType = typename Traits::RequestType; 71 using RequestType = typename Traits::RequestType;
72 using ImplPointerType = typename Traits::ImplPointerType;
70 73
71 BindingSetBase() {} 74 BindingSetBase() {}
72 75
73 void set_connection_error_handler(const base::Closure& error_handler) { 76 void set_connection_error_handler(const base::Closure& error_handler) {
74 error_handler_ = error_handler; 77 error_handler_ = error_handler;
75 error_with_reason_handler_.Reset(); 78 error_with_reason_handler_.Reset();
76 } 79 }
77 80
78 void set_connection_error_with_reason_handler( 81 void set_connection_error_with_reason_handler(
79 const ConnectionErrorWithReasonCallback& error_handler) { 82 const ConnectionErrorWithReasonCallback& error_handler) {
80 error_with_reason_handler_ = error_handler; 83 error_with_reason_handler_ = error_handler;
81 error_handler_.Reset(); 84 error_handler_.Reset();
82 } 85 }
83 86
84 // Sets a callback to be invoked immediately before dispatching any message or 87 // Sets a callback to be invoked immediately before dispatching any message or
85 // error received by any of the bindings in the set. This may only be used 88 // error received by any of the bindings in the set. This may only be used
86 // with a non-void |ContextType|. 89 // with a non-void |ContextType|.
87 void set_pre_dispatch_handler(const PreDispatchCallback& handler) { 90 void set_pre_dispatch_handler(const PreDispatchCallback& handler) {
88 static_assert(ContextTraits::SupportsContext(), 91 static_assert(ContextTraits::SupportsContext(),
89 "Pre-dispatch handler usage requires non-void context type."); 92 "Pre-dispatch handler usage requires non-void context type.");
90 pre_dispatch_handler_ = handler; 93 pre_dispatch_handler_ = handler;
91 } 94 }
92 95
93 // Adds a new binding to the set which binds |request| to |impl| with no 96 // Adds a new binding to the set which binds |request| to |impl| with no
94 // additional context. 97 // additional context.
95 BindingId AddBinding(Interface* impl, RequestType request) { 98 BindingId AddBinding(ImplPointerType impl, RequestType request) {
96 static_assert(!ContextTraits::SupportsContext(), 99 static_assert(!ContextTraits::SupportsContext(),
97 "Context value required for non-void context type."); 100 "Context value required for non-void context type.");
98 return AddBindingImpl(impl, std::move(request), false); 101 return AddBindingImpl(std::move(impl), std::move(request), false);
99 } 102 }
100 103
101 // Adds a new binding associated with |context|. 104 // Adds a new binding associated with |context|.
102 BindingId AddBinding(Interface* impl, RequestType request, Context context) { 105 BindingId AddBinding(ImplPointerType impl,
106 RequestType request,
107 Context context) {
103 static_assert(ContextTraits::SupportsContext(), 108 static_assert(ContextTraits::SupportsContext(),
104 "Context value unsupported for void context type."); 109 "Context value unsupported for void context type.");
105 return AddBindingImpl(impl, std::move(request), std::move(context)); 110 return AddBindingImpl(std::move(impl), std::move(request),
111 std::move(context));
106 } 112 }
107 113
108 // Removes a binding from the set. Note that this is safe to call even if the 114 // Removes a binding from the set. Note that this is safe to call even if the
109 // binding corresponding to |id| has already been removed. 115 // binding corresponding to |id| has already been removed.
110 // 116 //
111 // Returns |true| if the binding was removed and |false| if it didn't exist. 117 // Returns |true| if the binding was removed and |false| if it didn't exist.
112 bool RemoveBinding(BindingId id) { 118 bool RemoveBinding(BindingId id) {
113 auto it = bindings_.find(id); 119 auto it = bindings_.find(id);
114 if (it == bindings_.end()) 120 if (it == bindings_.end())
115 return false; 121 return false;
116 bindings_.erase(it); 122 bindings_.erase(it);
117 return true; 123 return true;
118 } 124 }
119 125
120 // Returns a proxy bound to one end of a pipe whose other end is bound to 126 // Returns a proxy bound to one end of a pipe whose other end is bound to
121 // |this|. If |id_storage| is not null, |*id_storage| will be set to the ID 127 // |this|. If |id_storage| is not null, |*id_storage| will be set to the ID
122 // of the added binding. 128 // of the added binding.
123 ProxyType CreateInterfacePtrAndBind(Interface* impl, 129 ProxyType CreateInterfacePtrAndBind(ImplPointerType impl,
124 BindingId* id_storage = nullptr) { 130 BindingId* id_storage = nullptr) {
125 ProxyType proxy; 131 ProxyType proxy;
126 BindingId id = AddBinding(impl, Traits::MakeRequest(&proxy)); 132 BindingId id = AddBinding(std::move(impl), Traits::MakeRequest(&proxy));
127 if (id_storage) 133 if (id_storage)
128 *id_storage = id; 134 *id_storage = id;
129 return proxy; 135 return proxy;
130 } 136 }
131 137
132 void CloseAllBindings() { bindings_.clear(); } 138 void CloseAllBindings() { bindings_.clear(); }
133 139
134 bool empty() const { return bindings_.empty(); } 140 bool empty() const { return bindings_.empty(); }
135 141
136 // Implementations may call this when processing a dispatched message or 142 // Implementations may call this when processing a dispatched message or
(...skipping 10 matching lines...) Expand all
147 void FlushForTesting() { 153 void FlushForTesting() {
148 for (auto& binding : bindings_) 154 for (auto& binding : bindings_)
149 binding.second->FlushForTesting(); 155 binding.second->FlushForTesting();
150 } 156 }
151 157
152 private: 158 private:
153 friend class Entry; 159 friend class Entry;
154 160
155 class Entry { 161 class Entry {
156 public: 162 public:
157 Entry(Interface* impl, 163 Entry(ImplPointerType impl,
158 RequestType request, 164 RequestType request,
159 BindingSetBase* binding_set, 165 BindingSetBase* binding_set,
160 BindingId binding_id, 166 BindingId binding_id,
161 Context context) 167 Context context)
162 : binding_(impl, std::move(request)), 168 : binding_(std::move(impl), std::move(request)),
163 binding_set_(binding_set), 169 binding_set_(binding_set),
164 binding_id_(binding_id), 170 binding_id_(binding_id),
165 context_(std::move(context)) { 171 context_(std::move(context)) {
166 if (ContextTraits::SupportsContext()) 172 if (ContextTraits::SupportsContext())
167 binding_.AddFilter(base::MakeUnique<DispatchFilter>(this)); 173 binding_.AddFilter(base::MakeUnique<DispatchFilter>(this));
168 binding_.set_connection_error_with_reason_handler( 174 binding_.set_connection_error_with_reason_handler(
169 base::Bind(&Entry::OnConnectionError, base::Unretained(this))); 175 base::Bind(&Entry::OnConnectionError, base::Unretained(this)));
170 } 176 }
171 177
172 void FlushForTesting() { binding_.FlushForTesting(); } 178 void FlushForTesting() { binding_.FlushForTesting(); }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 DISALLOW_COPY_AND_ASSIGN(Entry); 215 DISALLOW_COPY_AND_ASSIGN(Entry);
210 }; 216 };
211 217
212 void SetDispatchContext(const Context* context) { 218 void SetDispatchContext(const Context* context) {
213 DCHECK(ContextTraits::SupportsContext()); 219 DCHECK(ContextTraits::SupportsContext());
214 dispatch_context_ = context; 220 dispatch_context_ = context;
215 if (!pre_dispatch_handler_.is_null()) 221 if (!pre_dispatch_handler_.is_null())
216 pre_dispatch_handler_.Run(*context); 222 pre_dispatch_handler_.Run(*context);
217 } 223 }
218 224
219 BindingId AddBindingImpl(Interface* impl, 225 BindingId AddBindingImpl(ImplPointerType impl,
220 RequestType request, 226 RequestType request,
221 Context context) { 227 Context context) {
222 BindingId id = next_binding_id_++; 228 BindingId id = next_binding_id_++;
223 DCHECK_GE(next_binding_id_, 0u); 229 DCHECK_GE(next_binding_id_, 0u);
224 auto entry = base::MakeUnique<Entry>( 230 auto entry = base::MakeUnique<Entry>(std::move(impl), std::move(request),
225 impl, std::move(request), this, id, std::move(context)); 231 this, id, std::move(context));
226 bindings_.insert(std::make_pair(id, std::move(entry))); 232 bindings_.insert(std::make_pair(id, std::move(entry)));
227 return id; 233 return id;
228 } 234 }
229 235
230 void OnConnectionError(BindingId id, 236 void OnConnectionError(BindingId id,
231 uint32_t custom_reason, 237 uint32_t custom_reason,
232 const std::string& description) { 238 const std::string& description) {
233 auto it = bindings_.find(id); 239 auto it = bindings_.find(id);
234 DCHECK(it != bindings_.end()); 240 DCHECK(it != bindings_.end());
235 241
(...skipping 16 matching lines...) Expand all
252 258
253 DISALLOW_COPY_AND_ASSIGN(BindingSetBase); 259 DISALLOW_COPY_AND_ASSIGN(BindingSetBase);
254 }; 260 };
255 261
256 template <typename Interface, typename ContextType = void> 262 template <typename Interface, typename ContextType = void>
257 using BindingSet = BindingSetBase<Interface, Binding<Interface>, ContextType>; 263 using BindingSet = BindingSetBase<Interface, Binding<Interface>, ContextType>;
258 264
259 } // namespace mojo 265 } // namespace mojo
260 266
261 #endif // MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ 267 #endif // MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698