| 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 |