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

Side by Side Diff: mojo/public/cpp/bindings/lib/binding_state.h

Issue 1473273003: Mojo C++ bindings: InterfacePtr<T> and Binding<T> use MultiplexRouter when T passes associated inte… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years 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 2015 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_PUBLIC_CPP_BINDINGS_LIB_BINDING_STATE_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDING_STATE_H_
7
8 #include "base/logging.h"
9 #include "base/macros.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "mojo/public/c/environment/async_waiter.h"
13 #include "mojo/public/cpp/bindings/associated_group.h"
14 #include "mojo/public/cpp/bindings/callback.h"
15 #include "mojo/public/cpp/bindings/interface_ptr.h"
16 #include "mojo/public/cpp/bindings/interface_ptr_info.h"
17 #include "mojo/public/cpp/bindings/interface_request.h"
18 #include "mojo/public/cpp/bindings/lib/filter_chain.h"
19 #include "mojo/public/cpp/bindings/lib/interface_endpoint_client.h"
20 #include "mojo/public/cpp/bindings/lib/interface_id.h"
21 #include "mojo/public/cpp/bindings/lib/message_header_validator.h"
22 #include "mojo/public/cpp/bindings/lib/multiplex_router.h"
23 #include "mojo/public/cpp/bindings/lib/router.h"
24 #include "mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h"
25 #include "mojo/public/cpp/system/core.h"
26
27 namespace mojo {
28 namespace internal {
29
30 template <typename Interface, bool use_multiplex_router>
31 class BindingState;
32
33 // Uses a single-threaded, dedicated router. If |Interface| doesn't have any
34 // methods to pass associated interface pointers or requests, there won't be
35 // multiple interfaces running on the underlying message pipe. In that case, we
36 // can use this specialization to reduce cost.
37 template <typename Interface>
38 class BindingState<Interface, false> {
39 public:
40 explicit BindingState(Interface* impl) : impl_(impl) {
41 stub_.set_sink(impl_);
42 }
43
44 ~BindingState() {
45 if (router_)
46 Close();
47 }
48
49 void Bind(ScopedMessagePipeHandle handle, const MojoAsyncWaiter* waiter) {
50 DCHECK(!router_);
51 internal::FilterChain filters;
52 filters.Append<internal::MessageHeaderValidator>();
53 filters.Append<typename Interface::RequestValidator_>();
54
55 router_ = new internal::Router(handle.Pass(), filters.Pass(), waiter);
56 router_->set_incoming_receiver(&stub_);
57 router_->set_connection_error_handler(
58 [this]() { connection_error_handler_.Run(); });
59 }
60
61 void PauseIncomingMethodCallProcessing() {
62 DCHECK(router_);
63 router_->PauseIncomingMethodCallProcessing();
64 }
65 void ResumeIncomingMethodCallProcessing() {
66 DCHECK(router_);
67 router_->ResumeIncomingMethodCallProcessing();
68 }
69
70 bool WaitForIncomingMethodCall(
71 MojoDeadline deadline = MOJO_DEADLINE_INDEFINITE) {
72 DCHECK(router_);
73 return router_->WaitForIncomingMessage(deadline);
74 }
75
76 void Close() {
77 DCHECK(router_);
78 router_->CloseMessagePipe();
79 DestroyRouter();
80 }
81
82 InterfaceRequest<Interface> Unbind() {
83 InterfaceRequest<Interface> request =
84 MakeRequest<Interface>(router_->PassMessagePipe());
85 DestroyRouter();
86 return request.Pass();
87 }
88
89 void set_connection_error_handler(const Closure& error_handler) {
90 connection_error_handler_ = error_handler;
91 }
92
93 Interface* impl() { return impl_; }
94
95 bool is_bound() const { return !!router_; }
96
97 MessagePipeHandle handle() const {
98 DCHECK(is_bound());
99 return router_->handle();
100 }
101
102 AssociatedGroup* associated_group() { return nullptr; }
103
104 void EnableTestingMode() {
105 DCHECK(is_bound());
106 router_->EnableTestingMode();
107 }
108
109 private:
110 void DestroyRouter() {
111 router_->set_connection_error_handler(Closure());
112 delete router_;
113 router_ = nullptr;
114 }
115
116 internal::Router* router_ = nullptr;
117 typename Interface::Stub_ stub_;
118 Interface* impl_;
119 Closure connection_error_handler_;
120
121 DISALLOW_COPY_AND_ASSIGN(BindingState);
122 };
123
124 // Uses a multiplexing router. If |Interface| has methods to pass associated
125 // interface pointers or requests, this specialization should be used.
126 template <typename Interface>
127 class BindingState<Interface, true> {
128 public:
129 explicit BindingState(Interface* impl) : impl_(impl) {
130 stub_.set_sink(impl_);
131 }
132
133 ~BindingState() {
134 if (router_)
135 Close();
136 }
137
138 void Bind(ScopedMessagePipeHandle handle, const MojoAsyncWaiter* waiter) {
139 DCHECK(!router_);
140
141 router_ = new internal::MultiplexRouter(false, handle.Pass(), waiter);
142 endpoint_client_.reset(new internal::InterfaceEndpointClient(
143 router_->CreateLocalEndpointHandle(internal::kMasterInterfaceId),
144 &stub_, make_scoped_ptr(new typename Interface::RequestValidator_())));
145
146 endpoint_client_->set_connection_error_handler(
147 [this]() { connection_error_handler_.Run(); });
148 }
149
150 void Close() {
151 DCHECK(router_);
152 endpoint_client_.reset();
153 router_->CloseMessagePipe();
154 router_ = nullptr;
155 }
156
157 InterfaceRequest<Interface> Unbind() {
158 endpoint_client_.reset();
159 InterfaceRequest<Interface> request =
160 MakeRequest<Interface>(router_->PassMessagePipe());
161 router_ = nullptr;
162 return request.Pass();
163 }
164
165 void set_connection_error_handler(const Closure& error_handler) {
166 connection_error_handler_ = error_handler;
167 }
168
169 Interface* impl() { return impl_; }
170
171 bool is_bound() const { return !!router_; }
172
173 MessagePipeHandle handle() const {
174 DCHECK(is_bound());
175 return router_->handle();
176 }
177
178 AssociatedGroup* associated_group() {
179 return endpoint_client_ ? endpoint_client_->associated_group() : nullptr;
180 }
181
182 void EnableTestingMode() {
183 DCHECK(is_bound());
184 router_->EnableTestingMode();
185 }
186
187 // Intentionally not defined:
188 // void PauseIncomingMethodCallProcessing();
189 // void ResumeIncomingMethodCallProcessing();
190 // bool WaitForIncomingMethodCall(MojoDeadline deadline);
191
192 private:
193 scoped_refptr<internal::MultiplexRouter> router_;
194 scoped_ptr<internal::InterfaceEndpointClient> endpoint_client_;
195
196 typename Interface::Stub_ stub_;
197 Interface* impl_;
198 Closure connection_error_handler_;
199
200 DISALLOW_COPY_AND_ASSIGN(BindingState);
201 };
202
203 } // namesapce internal
204 } // namespace mojo
205
206 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDING_STATE_H_
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h ('k') | mojo/public/cpp/bindings/lib/interface_ptr_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698