10de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 20de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 30de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// found in the LICENSE file. 40de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 50de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#ifndef MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_H_ 60de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#define MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_H_ 70de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 80de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include <algorithm> 90de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 100de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "mojo/public/cpp/bindings/error_handler.h" 110de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "mojo/public/cpp/bindings/lib/interface_ptr_internal.h" 126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "mojo/public/cpp/environment/environment.h" 130de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "mojo/public/cpp/system/macros.h" 140de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 150de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)namespace mojo { 160de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)class ErrorHandler; 170de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 180de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// InterfacePtr represents a proxy to a remote instance of an interface. 190de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)template <typename Interface> 200de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)class InterfacePtr { 210de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(InterfacePtr, RValue) 220de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) public: 230de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) InterfacePtr() {} 240de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 250de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) InterfacePtr(RValue other) { 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) internal_state_.Swap(&other.object->internal_state_); 270de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 280de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) InterfacePtr& operator=(RValue other) { 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reset(); 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) internal_state_.Swap(&other.object->internal_state_); 310de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) return *this; 320de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 330de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 340de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) ~InterfacePtr() {} 350de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 360de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) Interface* get() const { 370de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) return internal_state_.instance(); 380de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 390de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) Interface* operator->() const { return get(); } 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Interface& operator*() const { return *get(); } 410de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 420de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) void reset() { 430de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) State doomed; 440de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) internal_state_.Swap(&doomed); 450de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 460de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Blocks the current thread for the first incoming method call, i.e., either 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // a call to a client method or a callback method. Returns |true| if a method 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // has been called, |false| in case of error. It must only be called on a 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // bound object. 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool WaitForIncomingMethodCall() { 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return internal_state_.WaitForIncomingMethodCall(); 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 550de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // This method configures the InterfacePtr<..> to be a proxy to a remote 560de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // object on the other end of the given pipe. 570de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // 580de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // The proxy is bound to the current thread, which means its methods may 590de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // only be called on the current thread. 600de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // To move a bound InterfacePtr<..> to another thread, call PassMessagePipe(). 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Then create a new InterfacePtr<..> on another thread, and bind the new 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // InterfacePtr<..> to the message pipe on that thread. 646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) void Bind( 656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) ScopedMessagePipeHandle handle, 666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { 670de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) reset(); 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch internal_state_.Bind(handle.Pass(), waiter); 690de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 700de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The client interface may only be set after this InterfacePtr<..> is bound. 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void set_client(typename Interface::Client* client) { 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) internal_state_.set_client(client); 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 760de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // This method may be called to query if the underlying pipe has encountered 770de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // an error. If true, this means method calls made on this interface will be 780de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // dropped (and may have already been dropped) on the floor. 790de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) bool encountered_error() const { 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return internal_state_.encountered_error(); 810de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 820de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 830de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // This method may be called to register an ErrorHandler to observe a 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // connection error on the underlying pipe. It must only be called on a bound 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // object. 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // The callback runs asynchronously from the current message loop. 870de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) void set_error_handler(ErrorHandler* error_handler) { 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch internal_state_.set_error_handler(error_handler); 890de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 900de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 910de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // Returns the underlying message pipe handle (if any) and resets the 920de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // InterfacePtr<..> to its uninitialized state. This method is helpful if you 930de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // need to move a proxy to another thread. See related notes for Bind. 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedMessagePipeHandle PassMessagePipe() { 950de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) State state; 960de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) internal_state_.Swap(&state); 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return state.PassMessagePipe(); 980de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 990de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 1000de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // DO NOT USE. Exposed only for internal use and for testing. 1010de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) internal::InterfacePtrState<Interface>* internal_state() { 1020de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) return &internal_state_; 1030de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 1040de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Allow InterfacePtr<> to be used in boolean expressions, but not 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // implicitly convertible to a real bool (which is dangerous). 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private: 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) typedef internal::InterfacePtrState<Interface> InterfacePtr::*Testable; 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public: 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) operator Testable() const { 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return internal_state_.is_bound() ? &InterfacePtr::internal_state_ : NULL; 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1150de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) private: 1160de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) typedef internal::InterfacePtrState<Interface> State; 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mutable State internal_state_; 1180de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)}; 1190de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 1200de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// Takes a handle to the proxy end-point of a pipe. On the other end is 1210de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// presumed to be an interface implementation of type |Interface|. Returns a 1220de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// generated proxy to that interface, which may be used on the current thread. 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// It is valid to call set_client on the returned InterfacePtr<..> to set an 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// instance of Interface::Client. 1250de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)template <typename Interface> 1260de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)InterfacePtr<Interface> MakeProxy( 1270de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) ScopedMessagePipeHandle handle, 1286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { 1290de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) InterfacePtr<Interface> ptr; 1300de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) if (handle.is_valid()) 1310de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) ptr.Bind(handle.Pass(), waiter); 1320de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) return ptr.Pass(); 1330de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)} 1340de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 1350de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)} // namespace mojo 1360de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 1370de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#endif // MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_H_ 138