blob: 179c1b975d9a4a64708fb6923f0ccf6ece2fb5ba [file] [log] [blame]
rockot85dce0862015-11-13 01:33:591// Copyright 2014 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_BINDING_H_
6#define MOJO_PUBLIC_CPP_BINDINGS_BINDING_H_
7
dchengaa6492d2015-12-26 04:46:368#include <utility>
9
yzshen0b5628a2015-11-25 05:58:1010#include "base/macros.h"
rockot85dce0862015-11-13 01:33:5911#include "mojo/public/c/environment/async_waiter.h"
12#include "mojo/public/cpp/bindings/callback.h"
13#include "mojo/public/cpp/bindings/interface_ptr.h"
14#include "mojo/public/cpp/bindings/interface_ptr_info.h"
15#include "mojo/public/cpp/bindings/interface_request.h"
yzshen0b5628a2015-11-25 05:58:1016#include "mojo/public/cpp/bindings/lib/binding_state.h"
rockot85dce0862015-11-13 01:33:5917#include "mojo/public/cpp/system/core.h"
18
19namespace mojo {
20
yzshen0b5628a2015-11-25 05:58:1021class AssociatedGroup;
22
rockot85dce0862015-11-13 01:33:5923// Represents the binding of an interface implementation to a message pipe.
24// When the |Binding| object is destroyed, the binding between the message pipe
25// and the interface is torn down and the message pipe is closed, leaving the
26// interface implementation in an unbound state.
27//
28// Example:
29//
30// #include "foo.mojom.h"
31//
32// class FooImpl : public Foo {
33// public:
34// explicit FooImpl(InterfaceRequest<Foo> request)
35// : binding_(this, request.Pass()) {}
36//
37// // Foo implementation here.
38//
39// private:
40// Binding<Foo> binding_;
41// };
42//
43// class MyFooFactory : public InterfaceFactory<Foo> {
44// public:
45// void Create(..., InterfaceRequest<Foo> request) override {
46// auto f = new FooImpl(request.Pass());
47// // Do something to manage the lifetime of |f|. Use StrongBinding<> to
48// // delete FooImpl on connection errors.
49// }
50// };
51//
52// The caller may specify a |MojoAsyncWaiter| to be used by the connection when
53// waiting for calls to arrive. Normally it is fine to use the default waiter.
54// However, the caller may provide their own implementation if needed. The
55// |Binding| will not take ownership of the waiter, and the waiter must outlive
56// the |Binding|. The provided waiter must be able to signal the implementation
57// which generally means it needs to be able to schedule work on the thread the
58// implementation runs on. If writing library code that has to work on different
59// types of threads callers may need to provide different waiter
60// implementations.
amistry913e9f12016-01-06 22:12:0361//
62// This class is thread hostile while bound to a message pipe. All calls to this
63// class must be from the thread that bound it. The interface implementation's
64// methods will be called from the thread that bound this. If a Binding is not
65// bound to a message pipe, it may be bound or destroyed on any thread.
rockot85dce0862015-11-13 01:33:5966template <typename Interface>
67class Binding {
68 public:
rockot54b52492015-12-17 03:21:5869 using GenericInterface = typename Interface::GenericInterface;
70
rockot85dce0862015-11-13 01:33:5971 // Constructs an incomplete binding that will use the implementation |impl|.
72 // The binding may be completed with a subsequent call to the |Bind| method.
73 // Does not take ownership of |impl|, which must outlive the binding.
yzshen0b5628a2015-11-25 05:58:1074 explicit Binding(Interface* impl) : internal_state_(impl) {}
rockot85dce0862015-11-13 01:33:5975
76 // Constructs a completed binding of message pipe |handle| to implementation
77 // |impl|. Does not take ownership of |impl|, which must outlive the binding.
78 // See class comment for definition of |waiter|.
79 Binding(Interface* impl,
80 ScopedMessagePipeHandle handle,
81 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter())
82 : Binding(impl) {
dchengaa6492d2015-12-26 04:46:3683 Bind(std::move(handle), waiter);
rockot85dce0862015-11-13 01:33:5984 }
85
86 // Constructs a completed binding of |impl| to a new message pipe, passing the
87 // client end to |ptr|, which takes ownership of it. The caller is expected to
88 // pass |ptr| on to the client of the service. Does not take ownership of any
89 // of the parameters. |impl| must outlive the binding. |ptr| only needs to
90 // last until the constructor returns. See class comment for definition of
91 // |waiter|.
92 Binding(Interface* impl,
93 InterfacePtr<Interface>* ptr,
94 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter())
95 : Binding(impl) {
96 Bind(ptr, waiter);
97 }
98
99 // Constructs a completed binding of |impl| to the message pipe endpoint in
100 // |request|, taking ownership of the endpoint. Does not take ownership of
101 // |impl|, which must outlive the binding. See class comment for definition of
102 // |waiter|.
103 Binding(Interface* impl,
rockot54b52492015-12-17 03:21:58104 InterfaceRequest<GenericInterface> request,
rockot85dce0862015-11-13 01:33:59105 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter())
106 : Binding(impl) {
107 Bind(request.PassMessagePipe(), waiter);
108 }
109
110 // Tears down the binding, closing the message pipe and leaving the interface
111 // implementation unbound.
yzshen0b5628a2015-11-25 05:58:10112 ~Binding() {}
rockot85dce0862015-11-13 01:33:59113
skyad19bf46a2016-01-21 18:59:47114 // Returns an InterfacePtr bound to one end of a pipe whose other end is
115 // bound to |this|.
116 InterfacePtr<Interface> CreateInterfacePtrAndBind() {
117 InterfacePtr<Interface> interface_ptr;
118 Bind(&interface_ptr);
119 return interface_ptr;
120 }
121
rockot85dce0862015-11-13 01:33:59122 // Completes a binding that was constructed with only an interface
123 // implementation. Takes ownership of |handle| and binds it to the previously
124 // specified implementation. See class comment for definition of |waiter|.
125 void Bind(
126 ScopedMessagePipeHandle handle,
127 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
dchengaa6492d2015-12-26 04:46:36128 internal_state_.Bind(std::move(handle), waiter);
rockot85dce0862015-11-13 01:33:59129 }
130
131 // Completes a binding that was constructed with only an interface
132 // implementation by creating a new message pipe, binding one end of it to the
133 // previously specified implementation, and passing the other to |ptr|, which
134 // takes ownership of it. The caller is expected to pass |ptr| on to the
135 // eventual client of the service. Does not take ownership of |ptr|. See
136 // class comment for definition of |waiter|.
137 void Bind(
138 InterfacePtr<Interface>* ptr,
139 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
140 MessagePipe pipe;
dchengaa6492d2015-12-26 04:46:36141 ptr->Bind(InterfacePtrInfo<Interface>(std::move(pipe.handle0),
142 Interface::Version_),
143 waiter);
144 Bind(std::move(pipe.handle1), waiter);
rockot85dce0862015-11-13 01:33:59145 }
146
147 // Completes a binding that was constructed with only an interface
148 // implementation by removing the message pipe endpoint from |request| and
149 // binding it to the previously specified implementation. See class comment
150 // for definition of |waiter|.
151 void Bind(
rockot54b52492015-12-17 03:21:58152 InterfaceRequest<GenericInterface> request,
rockot85dce0862015-11-13 01:33:59153 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
154 Bind(request.PassMessagePipe(), waiter);
155 }
156
yzshen1e8f6662015-12-11 01:37:50157 // Whether there are any associated interfaces running on the pipe currently.
158 bool HasAssociatedInterfaces() const {
159 return internal_state_.HasAssociatedInterfaces();
160 }
161
rockot85dce0862015-11-13 01:33:59162 // Stops processing incoming messages until
163 // ResumeIncomingMethodCallProcessing(), or WaitForIncomingMethodCall().
164 // Outgoing messages are still sent.
165 //
166 // No errors are detected on the message pipe while paused.
yzshen0b5628a2015-11-25 05:58:10167 //
yzshen1e8f6662015-12-11 01:37:50168 // This method may only be called if the object has been bound to a message
169 // pipe and there are no associated interfaces running.
rockot85dce0862015-11-13 01:33:59170 void PauseIncomingMethodCallProcessing() {
yzshen1e8f6662015-12-11 01:37:50171 CHECK(!HasAssociatedInterfaces());
yzshen0b5628a2015-11-25 05:58:10172 internal_state_.PauseIncomingMethodCallProcessing();
rockot85dce0862015-11-13 01:33:59173 }
174 void ResumeIncomingMethodCallProcessing() {
yzshen0b5628a2015-11-25 05:58:10175 internal_state_.ResumeIncomingMethodCallProcessing();
rockot85dce0862015-11-13 01:33:59176 }
177
178 // Blocks the calling thread until either a call arrives on the previously
179 // bound message pipe, the deadline is exceeded, or an error occurs. Returns
180 // true if a method was successfully read and dispatched.
yzshen0b5628a2015-11-25 05:58:10181 //
yzshen1e8f6662015-12-11 01:37:50182 // This method may only be called if the object has been bound to a message
183 // pipe and there are no associated interfaces running.
rockot85dce0862015-11-13 01:33:59184 bool WaitForIncomingMethodCall(
185 MojoDeadline deadline = MOJO_DEADLINE_INDEFINITE) {
yzshen1e8f6662015-12-11 01:37:50186 CHECK(!HasAssociatedInterfaces());
yzshen0b5628a2015-11-25 05:58:10187 return internal_state_.WaitForIncomingMethodCall(deadline);
rockot85dce0862015-11-13 01:33:59188 }
189
190 // Closes the message pipe that was previously bound. Put this object into a
191 // state where it can be rebound to a new pipe.
yzshen0b5628a2015-11-25 05:58:10192 void Close() { internal_state_.Close(); }
rockot85dce0862015-11-13 01:33:59193
194 // Unbinds the underlying pipe from this binding and returns it so it can be
195 // used in another context, such as on another thread or with a different
196 // implementation. Put this object into a state where it can be rebound to a
197 // new pipe.
yzshen1e8f6662015-12-11 01:37:50198 //
199 // This method may only be called if the object has been bound to a message
200 // pipe and there are no associated interfaces running.
201 //
202 // TODO(yzshen): For now, users need to make sure there is no one holding
203 // on to associated interface endpoint handles at both sides of the
204 // message pipe in order to call this method. We need a way to forcefully
205 // invalidate associated interface endpoint handles.
rockot54b52492015-12-17 03:21:58206 InterfaceRequest<GenericInterface> Unbind() {
yzshen1e8f6662015-12-11 01:37:50207 CHECK(!HasAssociatedInterfaces());
208 return internal_state_.Unbind();
209 }
rockot85dce0862015-11-13 01:33:59210
211 // Sets an error handler that will be called if a connection error occurs on
212 // the bound message pipe.
amistryf70387572015-12-17 05:23:43213 //
214 // This method may only be called after this Binding has been bound to a
215 // message pipe. The error handler will be reset when this Binding is unbound
216 // or closed.
rockot85dce0862015-11-13 01:33:59217 void set_connection_error_handler(const Closure& error_handler) {
amistryf70387572015-12-17 05:23:43218 DCHECK(is_bound());
yzshen0b5628a2015-11-25 05:58:10219 internal_state_.set_connection_error_handler(error_handler);
rockot85dce0862015-11-13 01:33:59220 }
221
222 // Returns the interface implementation that was previously specified. Caller
223 // does not take ownership.
yzshen0b5628a2015-11-25 05:58:10224 Interface* impl() { return internal_state_.impl(); }
rockot85dce0862015-11-13 01:33:59225
226 // Indicates whether the binding has been completed (i.e., whether a message
227 // pipe has been bound to the implementation).
yzshen0b5628a2015-11-25 05:58:10228 bool is_bound() const { return internal_state_.is_bound(); }
rockot85dce0862015-11-13 01:33:59229
230 // Returns the value of the handle currently bound to this Binding which can
231 // be used to make explicit Wait/WaitMany calls. Requires that the Binding be
232 // bound. Ownership of the handle is retained by the Binding, it is not
233 // transferred to the caller.
yzshen0b5628a2015-11-25 05:58:10234 MessagePipeHandle handle() const { return internal_state_.handle(); }
235
236 // Returns the associated group that this object belongs to. Returns null if:
237 // - this object is not bound; or
238 // - the interface doesn't have methods to pass associated interface
239 // pointers or requests.
240 AssociatedGroup* associated_group() {
241 return internal_state_.associated_group();
rockot85dce0862015-11-13 01:33:59242 }
243
244 // Exposed for testing, should not generally be used.
yzshen0b5628a2015-11-25 05:58:10245 void EnableTestingMode() { internal_state_.EnableTestingMode(); }
rockot85dce0862015-11-13 01:33:59246
247 private:
yzshen0b5628a2015-11-25 05:58:10248 internal::BindingState<Interface, Interface::PassesAssociatedKinds_>
249 internal_state_;
rockot85dce0862015-11-13 01:33:59250
yzshen0b5628a2015-11-25 05:58:10251 DISALLOW_COPY_AND_ASSIGN(Binding);
rockot85dce0862015-11-13 01:33:59252};
253
254} // namespace mojo
255
256#endif // MOJO_PUBLIC_CPP_BINDINGS_BINDING_H_