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