OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_H_ | |
6 #define MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_H_ | |
7 | |
8 #include <algorithm> | |
9 #include <cstddef> | |
10 | |
11 #include "mojo/public/cpp/bindings/callback.h" | |
12 #include "mojo/public/cpp/bindings/interface_handle.h" | |
13 #include "mojo/public/cpp/bindings/lib/interface_ptr_internal.h" | |
14 #include "mojo/public/cpp/environment/environment.h" | |
15 #include "mojo/public/cpp/system/macros.h" | |
16 | |
17 namespace mojo { | |
18 | |
19 // A pointer to a local proxy of a remote Interface implementation. Uses a | |
20 // message pipe to communicate with the remote implementation, and automatically | |
21 // closes the pipe and deletes the proxy on destruction. The pointer must be | |
22 // bound to a message pipe before the interface methods can be called. | |
23 // | |
24 // This class is thread hostile, as is the local proxy it manages. All calls to | |
25 // this class or the proxy should be from the same thread that created it. If | |
26 // you need to move the proxy to a different thread, extract the | |
27 // InterfaceHandle (containing just the message pipe and any version | |
28 // information) using PassInterfaceHandle(), pass it to a different thread, and | |
29 // create and bind a new InterfacePtr from that thread. | |
30 template <typename Interface> | |
31 class InterfacePtr { | |
32 public: | |
33 // Constructs an unbound InterfacePtr. | |
34 InterfacePtr() {} | |
35 InterfacePtr(std::nullptr_t) {} | |
36 | |
37 // Takes over the binding of another InterfacePtr. | |
38 InterfacePtr(InterfacePtr&& other) { | |
39 internal_state_.Swap(&other.internal_state_); | |
40 } | |
41 | |
42 // Takes over the binding of another InterfacePtr, and closes any message pipe | |
43 // already bound to this pointer. | |
44 InterfacePtr& operator=(InterfacePtr&& other) { | |
45 reset(); | |
46 internal_state_.Swap(&other.internal_state_); | |
47 return *this; | |
48 } | |
49 | |
50 // Assigning nullptr to this class causes it to close the currently bound | |
51 // message pipe (if any) and returns the pointer to the unbound state. | |
52 InterfacePtr& operator=(std::nullptr_t) { | |
53 reset(); | |
54 return *this; | |
55 } | |
56 | |
57 // Closes the bound message pipe (if any) on destruction. | |
58 ~InterfacePtr() {} | |
59 | |
60 // If |info| is valid (containing a valid message pipe handle), returns an | |
61 // InterfacePtr bound to it. Otherwise, returns an unbound InterfacePtr. The | |
62 // specified |waiter| will be used as in the InterfacePtr::Bind() method. | |
63 static InterfacePtr<Interface> Create( | |
64 InterfaceHandle<Interface> info, | |
65 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { | |
66 InterfacePtr<Interface> ptr; | |
67 if (info.is_valid()) | |
68 ptr.Bind(info.Pass(), waiter); | |
69 return ptr; | |
70 } | |
71 | |
72 // Binds the InterfacePtr to a remote implementation of Interface. The | |
73 // |waiter| is used for receiving notifications when there is data to read | |
74 // from the message pipe. For most callers, the default |waiter| will be | |
75 // sufficient. | |
76 // | |
77 // Calling with an invalid |info| (containing an invalid message pipe handle) | |
78 // has the same effect as reset(). In this case, the InterfacePtr is not | |
79 // considered as bound. | |
80 void Bind( | |
81 InterfaceHandle<Interface> info, | |
82 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { | |
83 reset(); | |
84 if (info.is_valid()) | |
85 internal_state_.Bind(info.Pass(), waiter); | |
86 } | |
87 | |
88 // Returns whether or not this InterfacePtr is bound to a message pipe. | |
89 bool is_bound() const { return internal_state_.is_bound(); } | |
90 | |
91 // Returns a raw pointer to the local proxy. Caller does not take ownership. | |
92 // Note that the local proxy is thread hostile, as stated above. | |
93 Interface* get() const { return internal_state_.instance(); } | |
94 | |
95 // Functions like a pointer to Interface. Must already be bound. | |
96 Interface* operator->() const { return get(); } | |
97 Interface& operator*() const { return *get(); } | |
98 | |
99 // Returns the version number of the interface that the remote side supports. | |
100 uint32_t version() const { return internal_state_.version(); } | |
101 | |
102 // Queries the max version that the remote side supports. On completion, the | |
103 // result will be returned as the input of |callback|. The version number of | |
104 // this interface pointer will also be updated. | |
105 void QueryVersion(const Callback<void(uint32_t)>& callback) { | |
106 internal_state_.QueryVersion(callback); | |
107 } | |
108 | |
109 // If the remote side doesn't support the specified version, it will close its | |
110 // end of the message pipe asynchronously. This does nothing if it's already | |
111 // known that the remote side supports the specified version, i.e., if | |
112 // |version <= this->version()|. | |
113 // | |
114 // After calling RequireVersion() with a version not supported by the remote | |
115 // side, all subsequent calls to interface methods will be ignored. | |
116 void RequireVersion(uint32_t version) { | |
117 internal_state_.RequireVersion(version); | |
118 } | |
119 | |
120 // Closes the bound message pipe (if any) and returns the pointer to the | |
121 // unbound state. | |
122 void reset() { | |
123 State doomed; | |
124 internal_state_.Swap(&doomed); | |
125 } | |
126 | |
127 // Tests as true if bound, false if not. | |
128 explicit operator bool() const { return internal_state_.is_bound(); } | |
129 | |
130 // Blocks the current thread until the next incoming response callback arrives | |
131 // or an error occurs. Returns |true| if a response arrived, or |false| in | |
132 // case of error. | |
133 // | |
134 // This method may only be called after the InterfacePtr has been bound to a | |
135 // message pipe. | |
136 bool WaitForIncomingResponse() { | |
137 return internal_state_.WaitForIncomingResponse(MOJO_DEADLINE_INDEFINITE); | |
138 } | |
139 | |
140 // Blocks the current thread until the next incoming response callback | |
141 // arrives, an error occurs, or the deadline exceeded. Returns |true| if a | |
142 // response arrived, or |false| otherwise. Use |encountered_error| to know | |
143 // if an error occurred, of if the deadline exceeded. | |
144 // | |
145 // This method may only be called after the InterfacePtr has been bound to a | |
146 // message pipe. | |
147 bool WaitForIncomingResponseWithTimeout(MojoDeadline deadline) { | |
148 return internal_state_.WaitForIncomingResponse(deadline); | |
149 } | |
150 | |
151 // Indicates whether the message pipe has encountered an error. If true, | |
152 // method calls made on this interface will be dropped (and may already have | |
153 // been dropped). | |
154 bool encountered_error() const { return internal_state_.encountered_error(); } | |
155 | |
156 // Registers a handler to receive error notifications. The handler will be | |
157 // called from the thread that owns this InterfacePtr. | |
158 // | |
159 // This method may only be called after the InterfacePtr has been bound to a | |
160 // message pipe. | |
161 void set_connection_error_handler(const Closure& error_handler) { | |
162 internal_state_.set_connection_error_handler(error_handler); | |
163 } | |
164 | |
165 // Unbinds the InterfacePtr and returns the information which could be used | |
166 // to setup an InterfacePtr again. This method may be used to move the proxy | |
167 // to a different thread (see class comments for details). | |
168 InterfaceHandle<Interface> PassInterfaceHandle() { | |
169 State state; | |
170 internal_state_.Swap(&state); | |
171 | |
172 return state.PassInterfaceHandle(); | |
173 } | |
174 | |
175 // DO NOT USE. Exposed only for internal use and for testing. | |
176 internal::InterfacePtrState<Interface>* internal_state() { | |
177 return &internal_state_; | |
178 } | |
179 | |
180 private: | |
181 typedef internal::InterfacePtrState<Interface> State; | |
182 mutable State internal_state_; | |
183 | |
184 MOJO_MOVE_ONLY_TYPE(InterfacePtr); | |
185 }; | |
186 | |
187 } // namespace mojo | |
188 | |
189 #endif // MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_H_ | |
OLD | NEW |