OLD | NEW |
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_H_ | 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_BINDING_H_ |
6 #define MOJO_PUBLIC_CPP_BINDINGS_BINDING_H_ | 6 #define MOJO_PUBLIC_CPP_BINDINGS_BINDING_H_ |
7 | 7 |
| 8 #include "base/macros.h" |
8 #include "mojo/public/c/environment/async_waiter.h" | 9 #include "mojo/public/c/environment/async_waiter.h" |
9 #include "mojo/public/cpp/bindings/callback.h" | 10 #include "mojo/public/cpp/bindings/callback.h" |
10 #include "mojo/public/cpp/bindings/interface_ptr.h" | 11 #include "mojo/public/cpp/bindings/interface_ptr.h" |
11 #include "mojo/public/cpp/bindings/interface_ptr_info.h" | 12 #include "mojo/public/cpp/bindings/interface_ptr_info.h" |
12 #include "mojo/public/cpp/bindings/interface_request.h" | 13 #include "mojo/public/cpp/bindings/interface_request.h" |
13 #include "mojo/public/cpp/bindings/lib/filter_chain.h" | 14 #include "mojo/public/cpp/bindings/lib/binding_state.h" |
14 #include "mojo/public/cpp/bindings/lib/message_header_validator.h" | |
15 #include "mojo/public/cpp/bindings/lib/router.h" | |
16 #include "mojo/public/cpp/environment/logging.h" | |
17 #include "mojo/public/cpp/system/core.h" | 15 #include "mojo/public/cpp/system/core.h" |
18 | 16 |
19 namespace mojo { | 17 namespace mojo { |
20 | 18 |
| 19 class AssociatedGroup; |
| 20 |
21 // Represents the binding of an interface implementation to a message pipe. | 21 // Represents the binding of an interface implementation to a message pipe. |
22 // When the |Binding| object is destroyed, the binding between the message pipe | 22 // When the |Binding| object is destroyed, the binding between the message pipe |
23 // and the interface is torn down and the message pipe is closed, leaving the | 23 // and the interface is torn down and the message pipe is closed, leaving the |
24 // interface implementation in an unbound state. | 24 // interface implementation in an unbound state. |
25 // | 25 // |
26 // Example: | 26 // Example: |
27 // | 27 // |
28 // #include "foo.mojom.h" | 28 // #include "foo.mojom.h" |
29 // | 29 // |
30 // class FooImpl : public Foo { | 30 // class FooImpl : public Foo { |
(...skipping 24 matching lines...) Expand all Loading... |
55 // which generally means it needs to be able to schedule work on the thread the | 55 // which generally means it needs to be able to schedule work on the thread the |
56 // implementation runs on. If writing library code that has to work on different | 56 // implementation runs on. If writing library code that has to work on different |
57 // types of threads callers may need to provide different waiter | 57 // types of threads callers may need to provide different waiter |
58 // implementations. | 58 // implementations. |
59 template <typename Interface> | 59 template <typename Interface> |
60 class Binding { | 60 class Binding { |
61 public: | 61 public: |
62 // Constructs an incomplete binding that will use the implementation |impl|. | 62 // Constructs an incomplete binding that will use the implementation |impl|. |
63 // The binding may be completed with a subsequent call to the |Bind| method. | 63 // The binding may be completed with a subsequent call to the |Bind| method. |
64 // Does not take ownership of |impl|, which must outlive the binding. | 64 // Does not take ownership of |impl|, which must outlive the binding. |
65 explicit Binding(Interface* impl) : impl_(impl) { stub_.set_sink(impl_); } | 65 explicit Binding(Interface* impl) : internal_state_(impl) {} |
66 | 66 |
67 // Constructs a completed binding of message pipe |handle| to implementation | 67 // Constructs a completed binding of message pipe |handle| to implementation |
68 // |impl|. Does not take ownership of |impl|, which must outlive the binding. | 68 // |impl|. Does not take ownership of |impl|, which must outlive the binding. |
69 // See class comment for definition of |waiter|. | 69 // See class comment for definition of |waiter|. |
70 Binding(Interface* impl, | 70 Binding(Interface* impl, |
71 ScopedMessagePipeHandle handle, | 71 ScopedMessagePipeHandle handle, |
72 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) | 72 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) |
73 : Binding(impl) { | 73 : Binding(impl) { |
74 Bind(handle.Pass(), waiter); | 74 Bind(handle.Pass(), waiter); |
75 } | 75 } |
(...skipping 17 matching lines...) Expand all Loading... |
93 // |waiter|. | 93 // |waiter|. |
94 Binding(Interface* impl, | 94 Binding(Interface* impl, |
95 InterfaceRequest<Interface> request, | 95 InterfaceRequest<Interface> request, |
96 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) | 96 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) |
97 : Binding(impl) { | 97 : Binding(impl) { |
98 Bind(request.PassMessagePipe(), waiter); | 98 Bind(request.PassMessagePipe(), waiter); |
99 } | 99 } |
100 | 100 |
101 // Tears down the binding, closing the message pipe and leaving the interface | 101 // Tears down the binding, closing the message pipe and leaving the interface |
102 // implementation unbound. | 102 // implementation unbound. |
103 ~Binding() { | 103 ~Binding() {} |
104 if (internal_router_) | |
105 Close(); | |
106 } | |
107 | 104 |
108 // Completes a binding that was constructed with only an interface | 105 // Completes a binding that was constructed with only an interface |
109 // implementation. Takes ownership of |handle| and binds it to the previously | 106 // implementation. Takes ownership of |handle| and binds it to the previously |
110 // specified implementation. See class comment for definition of |waiter|. | 107 // specified implementation. See class comment for definition of |waiter|. |
111 void Bind( | 108 void Bind( |
112 ScopedMessagePipeHandle handle, | 109 ScopedMessagePipeHandle handle, |
113 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { | 110 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { |
114 MOJO_DCHECK(!internal_router_); | 111 internal_state_.Bind(handle.Pass(), waiter); |
115 internal::FilterChain filters; | |
116 filters.Append<internal::MessageHeaderValidator>(); | |
117 filters.Append<typename Interface::RequestValidator_>(); | |
118 | |
119 internal_router_ = | |
120 new internal::Router(handle.Pass(), filters.Pass(), waiter); | |
121 internal_router_->set_incoming_receiver(&stub_); | |
122 internal_router_->set_connection_error_handler( | |
123 [this]() { connection_error_handler_.Run(); }); | |
124 } | 112 } |
125 | 113 |
126 // Completes a binding that was constructed with only an interface | 114 // Completes a binding that was constructed with only an interface |
127 // implementation by creating a new message pipe, binding one end of it to the | 115 // implementation by creating a new message pipe, binding one end of it to the |
128 // previously specified implementation, and passing the other to |ptr|, which | 116 // previously specified implementation, and passing the other to |ptr|, which |
129 // takes ownership of it. The caller is expected to pass |ptr| on to the | 117 // takes ownership of it. The caller is expected to pass |ptr| on to the |
130 // eventual client of the service. Does not take ownership of |ptr|. See | 118 // eventual client of the service. Does not take ownership of |ptr|. See |
131 // class comment for definition of |waiter|. | 119 // class comment for definition of |waiter|. |
132 void Bind( | 120 void Bind( |
133 InterfacePtr<Interface>* ptr, | 121 InterfacePtr<Interface>* ptr, |
(...skipping 13 matching lines...) Expand all Loading... |
147 InterfaceRequest<Interface> request, | 135 InterfaceRequest<Interface> request, |
148 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { | 136 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { |
149 Bind(request.PassMessagePipe(), waiter); | 137 Bind(request.PassMessagePipe(), waiter); |
150 } | 138 } |
151 | 139 |
152 // Stops processing incoming messages until | 140 // Stops processing incoming messages until |
153 // ResumeIncomingMethodCallProcessing(), or WaitForIncomingMethodCall(). | 141 // ResumeIncomingMethodCallProcessing(), or WaitForIncomingMethodCall(). |
154 // Outgoing messages are still sent. | 142 // Outgoing messages are still sent. |
155 // | 143 // |
156 // No errors are detected on the message pipe while paused. | 144 // No errors are detected on the message pipe while paused. |
| 145 // |
| 146 // NOTE: Not supported (yet) if |Interface| has methods to pass associated |
| 147 // interface pointers/requests. |
157 void PauseIncomingMethodCallProcessing() { | 148 void PauseIncomingMethodCallProcessing() { |
158 MOJO_DCHECK(internal_router_); | 149 internal_state_.PauseIncomingMethodCallProcessing(); |
159 internal_router_->PauseIncomingMethodCallProcessing(); | |
160 } | 150 } |
| 151 // NOTE: Not supported (yet) if |Interface| has methods to pass associated |
| 152 // interface pointers/requests. |
161 void ResumeIncomingMethodCallProcessing() { | 153 void ResumeIncomingMethodCallProcessing() { |
162 MOJO_DCHECK(internal_router_); | 154 internal_state_.ResumeIncomingMethodCallProcessing(); |
163 internal_router_->ResumeIncomingMethodCallProcessing(); | |
164 } | 155 } |
165 | 156 |
166 // Blocks the calling thread until either a call arrives on the previously | 157 // Blocks the calling thread until either a call arrives on the previously |
167 // bound message pipe, the deadline is exceeded, or an error occurs. Returns | 158 // bound message pipe, the deadline is exceeded, or an error occurs. Returns |
168 // true if a method was successfully read and dispatched. | 159 // true if a method was successfully read and dispatched. |
| 160 // |
| 161 // NOTE: Not supported (yet) if |Interface| has methods to pass associated |
| 162 // interface pointers/requests. |
169 bool WaitForIncomingMethodCall( | 163 bool WaitForIncomingMethodCall( |
170 MojoDeadline deadline = MOJO_DEADLINE_INDEFINITE) { | 164 MojoDeadline deadline = MOJO_DEADLINE_INDEFINITE) { |
171 MOJO_DCHECK(internal_router_); | 165 return internal_state_.WaitForIncomingMethodCall(deadline); |
172 return internal_router_->WaitForIncomingMessage(deadline); | |
173 } | 166 } |
174 | 167 |
175 // Closes the message pipe that was previously bound. Put this object into a | 168 // Closes the message pipe that was previously bound. Put this object into a |
176 // state where it can be rebound to a new pipe. | 169 // state where it can be rebound to a new pipe. |
177 void Close() { | 170 void Close() { internal_state_.Close(); } |
178 MOJO_DCHECK(internal_router_); | |
179 internal_router_->CloseMessagePipe(); | |
180 DestroyRouter(); | |
181 } | |
182 | 171 |
183 // Unbinds the underlying pipe from this binding and returns it so it can be | 172 // Unbinds the underlying pipe from this binding and returns it so it can be |
184 // used in another context, such as on another thread or with a different | 173 // used in another context, such as on another thread or with a different |
185 // implementation. Put this object into a state where it can be rebound to a | 174 // implementation. Put this object into a state where it can be rebound to a |
186 // new pipe. | 175 // new pipe. |
187 InterfaceRequest<Interface> Unbind() { | 176 InterfaceRequest<Interface> Unbind() { return internal_state_.Unbind(); } |
188 InterfaceRequest<Interface> request = | |
189 MakeRequest<Interface>(internal_router_->PassMessagePipe()); | |
190 DestroyRouter(); | |
191 // TODO(vtl): The |.Pass()| below is only needed due to an MSVS bug; remove | |
192 // it once that's fixed. | |
193 return request.Pass(); | |
194 } | |
195 | 177 |
196 // Sets an error handler that will be called if a connection error occurs on | 178 // Sets an error handler that will be called if a connection error occurs on |
197 // the bound message pipe. | 179 // the bound message pipe. |
198 void set_connection_error_handler(const Closure& error_handler) { | 180 void set_connection_error_handler(const Closure& error_handler) { |
199 connection_error_handler_ = error_handler; | 181 internal_state_.set_connection_error_handler(error_handler); |
200 } | 182 } |
201 | 183 |
202 // Returns the interface implementation that was previously specified. Caller | 184 // Returns the interface implementation that was previously specified. Caller |
203 // does not take ownership. | 185 // does not take ownership. |
204 Interface* impl() { return impl_; } | 186 Interface* impl() { return internal_state_.impl(); } |
205 | 187 |
206 // Indicates whether the binding has been completed (i.e., whether a message | 188 // Indicates whether the binding has been completed (i.e., whether a message |
207 // pipe has been bound to the implementation). | 189 // pipe has been bound to the implementation). |
208 bool is_bound() const { return !!internal_router_; } | 190 bool is_bound() const { return internal_state_.is_bound(); } |
209 | 191 |
210 // Returns the value of the handle currently bound to this Binding which can | 192 // Returns the value of the handle currently bound to this Binding which can |
211 // be used to make explicit Wait/WaitMany calls. Requires that the Binding be | 193 // be used to make explicit Wait/WaitMany calls. Requires that the Binding be |
212 // bound. Ownership of the handle is retained by the Binding, it is not | 194 // bound. Ownership of the handle is retained by the Binding, it is not |
213 // transferred to the caller. | 195 // transferred to the caller. |
214 MessagePipeHandle handle() const { | 196 MessagePipeHandle handle() const { return internal_state_.handle(); } |
215 MOJO_DCHECK(is_bound()); | 197 |
216 return internal_router_->handle(); | 198 // Returns the associated group that this object belongs to. Returns null if: |
| 199 // - this object is not bound; or |
| 200 // - the interface doesn't have methods to pass associated interface |
| 201 // pointers or requests. |
| 202 AssociatedGroup* associated_group() { |
| 203 return internal_state_.associated_group(); |
217 } | 204 } |
218 | 205 |
219 // Exposed for testing, should not generally be used. | 206 // Exposed for testing, should not generally be used. |
220 internal::Router* internal_router() { return internal_router_; } | 207 void EnableTestingMode() { internal_state_.EnableTestingMode(); } |
221 | 208 |
222 private: | 209 private: |
223 void DestroyRouter() { | 210 internal::BindingState<Interface, Interface::PassesAssociatedKinds_> |
224 internal_router_->set_connection_error_handler(Closure()); | 211 internal_state_; |
225 delete internal_router_; | |
226 internal_router_ = nullptr; | |
227 } | |
228 | 212 |
229 internal::Router* internal_router_ = nullptr; | 213 DISALLOW_COPY_AND_ASSIGN(Binding); |
230 typename Interface::Stub_ stub_; | |
231 Interface* impl_; | |
232 Closure connection_error_handler_; | |
233 | |
234 MOJO_DISALLOW_COPY_AND_ASSIGN(Binding); | |
235 }; | 214 }; |
236 | 215 |
237 } // namespace mojo | 216 } // namespace mojo |
238 | 217 |
239 #endif // MOJO_PUBLIC_CPP_BINDINGS_BINDING_H_ | 218 #endif // MOJO_PUBLIC_CPP_BINDINGS_BINDING_H_ |
OLD | NEW |