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 10 #include "mojo/public/cpp/bindings/error_handler.h" 11 #include "mojo/public/cpp/bindings/lib/interface_ptr_internal.h" 12 #include "mojo/public/cpp/environment/environment.h" 13 #include "mojo/public/cpp/system/macros.h" 14 15 namespace mojo { 16 class ErrorHandler; 17 18 // InterfacePtr represents a proxy to a remote instance of an interface. 19 template <typename Interface> 20 class InterfacePtr { MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(InterfacePtr,RValue)21 MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(InterfacePtr, RValue) 22 public: 23 InterfacePtr() {} 24 InterfacePtr(RValue other)25 InterfacePtr(RValue other) { 26 internal_state_.Swap(&other.object->internal_state_); 27 } 28 InterfacePtr& operator=(RValue other) { 29 reset(); 30 internal_state_.Swap(&other.object->internal_state_); 31 return *this; 32 } 33 ~InterfacePtr()34 ~InterfacePtr() {} 35 get()36 Interface* get() const { 37 return internal_state_.instance(); 38 } 39 Interface* operator->() const { return get(); } 40 Interface& operator*() const { return *get(); } 41 reset()42 void reset() { 43 State doomed; 44 internal_state_.Swap(&doomed); 45 } 46 47 // Blocks the current thread for the first incoming method call, i.e., either 48 // a call to a client method or a callback method. Returns |true| if a method 49 // has been called, |false| in case of error. It must only be called on a 50 // bound object. WaitForIncomingMethodCall()51 bool WaitForIncomingMethodCall() { 52 return internal_state_.WaitForIncomingMethodCall(); 53 } 54 55 // This method configures the InterfacePtr<..> to be a proxy to a remote 56 // object on the other end of the given pipe. 57 // 58 // The proxy is bound to the current thread, which means its methods may 59 // only be called on the current thread. 60 // 61 // To move a bound InterfacePtr<..> to another thread, call PassMessagePipe(). 62 // Then create a new InterfacePtr<..> on another thread, and bind the new 63 // InterfacePtr<..> to the message pipe on that thread. 64 void Bind( 65 ScopedMessagePipeHandle handle, 66 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { 67 reset(); 68 internal_state_.Bind(handle.Pass(), waiter); 69 } 70 71 // The client interface may only be set after this InterfacePtr<..> is bound. set_client(typename Interface::Client * client)72 void set_client(typename Interface::Client* client) { 73 internal_state_.set_client(client); 74 } 75 76 // This method may be called to query if the underlying pipe has encountered 77 // an error. If true, this means method calls made on this interface will be 78 // dropped (and may have already been dropped) on the floor. encountered_error()79 bool encountered_error() const { 80 return internal_state_.encountered_error(); 81 } 82 83 // This method may be called to register an ErrorHandler to observe a 84 // connection error on the underlying pipe. It must only be called on a bound 85 // object. 86 // The callback runs asynchronously from the current message loop. set_error_handler(ErrorHandler * error_handler)87 void set_error_handler(ErrorHandler* error_handler) { 88 internal_state_.set_error_handler(error_handler); 89 } 90 91 // Returns the underlying message pipe handle (if any) and resets the 92 // InterfacePtr<..> to its uninitialized state. This method is helpful if you 93 // need to move a proxy to another thread. See related notes for Bind. PassMessagePipe()94 ScopedMessagePipeHandle PassMessagePipe() { 95 State state; 96 internal_state_.Swap(&state); 97 return state.PassMessagePipe(); 98 } 99 100 // DO NOT USE. Exposed only for internal use and for testing. internal_state()101 internal::InterfacePtrState<Interface>* internal_state() { 102 return &internal_state_; 103 } 104 105 // Allow InterfacePtr<> to be used in boolean expressions, but not 106 // implicitly convertible to a real bool (which is dangerous). 107 private: 108 typedef internal::InterfacePtrState<Interface> InterfacePtr::*Testable; 109 110 public: Testable()111 operator Testable() const { 112 return internal_state_.is_bound() ? &InterfacePtr::internal_state_ : NULL; 113 } 114 115 private: 116 typedef internal::InterfacePtrState<Interface> State; 117 mutable State internal_state_; 118 }; 119 120 // Takes a handle to the proxy end-point of a pipe. On the other end is 121 // presumed to be an interface implementation of type |Interface|. Returns a 122 // generated proxy to that interface, which may be used on the current thread. 123 // It is valid to call set_client on the returned InterfacePtr<..> to set an 124 // instance of Interface::Client. 125 template <typename Interface> 126 InterfacePtr<Interface> MakeProxy( 127 ScopedMessagePipeHandle handle, 128 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { 129 InterfacePtr<Interface> ptr; 130 if (handle.is_valid()) 131 ptr.Bind(handle.Pass(), waiter); 132 return ptr.Pass(); 133 } 134 135 } // namespace mojo 136 137 #endif // MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_H_ 138