1 // Copyright 2015 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_ASSOCIATED_GROUP_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_GROUP_H_ 7 8 #include <utility> 9 10 #include "base/memory/ref_counted.h" 11 #include "mojo/public/cpp/bindings/associated_interface_ptr_info.h" 12 #include "mojo/public/cpp/bindings/associated_interface_request.h" 13 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" 14 15 namespace mojo { 16 17 class AssociatedGroupController; 18 19 // AssociatedGroup refers to all the interface endpoints running at one end of a 20 // message pipe. It is used to create associated interfaces for that message 21 // pipe. 22 // It is thread safe and cheap to make copies. 23 class AssociatedGroup { 24 public: 25 // Configuration used by CreateAssociatedInterface(). Please see the comments 26 // of that method for more details. 27 enum AssociatedInterfaceConfig { WILL_PASS_PTR, WILL_PASS_REQUEST }; 28 29 AssociatedGroup(); 30 AssociatedGroup(const AssociatedGroup& other); 31 32 ~AssociatedGroup(); 33 34 AssociatedGroup& operator=(const AssociatedGroup& other); 35 36 // |config| indicates whether |ptr_info| or |request| will be sent to the 37 // remote side of the message pipe. 38 // 39 // NOTE: If |config| is |WILL_PASS_REQUEST|, you will want to bind |ptr_info| 40 // to a local AssociatedInterfacePtr to make calls. However, there is one 41 // restriction: the pointer should NOT be used to make calls before |request| 42 // is sent. Violating that will cause the message pipe to be closed. On the 43 // other hand, as soon as |request| is sent, the pointer is usable. There is 44 // no need to wait until |request| is bound to an implementation at the remote 45 // side. 46 template <typename T> CreateAssociatedInterface(AssociatedInterfaceConfig config,AssociatedInterfacePtrInfo<T> * ptr_info,AssociatedInterfaceRequest<T> * request)47 void CreateAssociatedInterface( 48 AssociatedInterfaceConfig config, 49 AssociatedInterfacePtrInfo<T>* ptr_info, 50 AssociatedInterfaceRequest<T>* request) { 51 ScopedInterfaceEndpointHandle local; 52 ScopedInterfaceEndpointHandle remote; 53 CreateEndpointHandlePair(&local, &remote); 54 55 if (!local.is_valid() || !remote.is_valid()) { 56 *ptr_info = AssociatedInterfacePtrInfo<T>(); 57 *request = AssociatedInterfaceRequest<T>(); 58 return; 59 } 60 61 if (config == WILL_PASS_PTR) { 62 ptr_info->set_handle(std::move(remote)); 63 64 // The implementation is local, therefore set the version according to 65 // the interface definition that this code is built against. 66 ptr_info->set_version(T::Version_); 67 request->Bind(std::move(local)); 68 } else { 69 ptr_info->set_handle(std::move(local)); 70 71 // The implementation is remote, we don't know about its actual version 72 // yet. 73 ptr_info->set_version(0u); 74 request->Bind(std::move(remote)); 75 } 76 } 77 78 private: 79 friend class AssociatedGroupController; 80 81 void CreateEndpointHandlePair( 82 ScopedInterfaceEndpointHandle* local_endpoint, 83 ScopedInterfaceEndpointHandle* remote_endpoint); 84 85 scoped_refptr<AssociatedGroupController> controller_; 86 }; 87 88 } // namespace mojo 89 90 #endif // MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_GROUP_H_ 91