service_connector.h revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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_APPLICATION_LIB_SERVICE_CONNECTOR_H_ 6#define MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_CONNECTOR_H_ 7 8#include <assert.h> 9 10#include <vector> 11 12#include "mojo/public/interfaces/service_provider/service_provider.mojom.h" 13 14namespace mojo { 15namespace internal { 16 17template <class ServiceImpl, typename Context> 18class ServiceConnector; 19 20// Specialization of ServiceConnection. 21// ServiceImpl: Subclass of InterfaceImpl<...>. 22// Context: Type of shared context. 23template <class ServiceImpl, typename Context> 24class ServiceConnection : public ServiceImpl { 25 public: 26 ServiceConnection() : ServiceImpl() {} 27 ServiceConnection(Context* context) : ServiceImpl(context) {} 28 29 virtual void OnConnectionError() MOJO_OVERRIDE { 30 service_connector_->RemoveConnection(static_cast<ServiceImpl*>(this)); 31 ServiceImpl::OnConnectionError(); 32 } 33 34private: 35 friend class ServiceConnector<ServiceImpl, Context>; 36 37 // Called shortly after this class is instantiated. 38 void set_service_connector( 39 ServiceConnector<ServiceImpl, Context>* connector) { 40 service_connector_ = connector; 41 } 42 43 ServiceConnector<ServiceImpl, Context>* service_connector_; 44}; 45 46template <typename ServiceImpl, typename Context> 47struct ServiceConstructor { 48 static ServiceConnection<ServiceImpl, Context>* New(Context* context) { 49 return new ServiceConnection<ServiceImpl, Context>(context); 50 } 51}; 52 53template <typename ServiceImpl> 54struct ServiceConstructor<ServiceImpl, void> { 55 public: 56 static ServiceConnection<ServiceImpl, void>* New(void* context) { 57 return new ServiceConnection<ServiceImpl, void>(); 58 } 59}; 60 61class ServiceConnectorBase { 62 public: 63 class Owner : public ServiceProvider { 64 public: 65 Owner(); 66 Owner(ScopedMessagePipeHandle service_provider_handle); 67 virtual ~Owner(); 68 virtual void AddServiceConnector( 69 internal::ServiceConnectorBase* service_connector) = 0; 70 virtual void RemoveServiceConnector( 71 internal::ServiceConnectorBase* service_connector) = 0; 72 73 protected: 74 void set_service_connector_owner(ServiceConnectorBase* service_connector, 75 Owner* owner) { 76 service_connector->owner_ = owner; 77 } 78 ServiceProviderPtr service_provider_; 79 }; 80 ServiceConnectorBase() : owner_(NULL) {} 81 virtual ~ServiceConnectorBase(); 82 virtual void ConnectToService(const std::string& url, 83 ScopedMessagePipeHandle client_handle) = 0; 84 85 protected: 86 Owner* owner_; 87}; 88 89template <class ServiceImpl, typename Context=void> 90class ServiceConnector : public internal::ServiceConnectorBase { 91 public: 92 ServiceConnector(Context* context = NULL) : context_(context) {} 93 94 virtual ~ServiceConnector() { 95 ConnectionList doomed; 96 doomed.swap(connections_); 97 for (typename ConnectionList::iterator it = doomed.begin(); 98 it != doomed.end(); ++it) { 99 delete *it; 100 } 101 assert(connections_.empty()); // No one should have added more! 102 } 103 104 virtual void ConnectToService(const std::string& url, 105 ScopedMessagePipeHandle handle) MOJO_OVERRIDE { 106 ServiceConnection<ServiceImpl, Context>* impl = 107 ServiceConstructor<ServiceImpl, Context>::New(context_); 108 impl->set_service_connector(this); 109 BindToPipe(impl, handle.Pass()); 110 111 connections_.push_back(impl); 112 } 113 114 void RemoveConnection(ServiceImpl* impl) { 115 // Called from ~ServiceImpl, in response to a connection error. 116 for (typename ConnectionList::iterator it = connections_.begin(); 117 it != connections_.end(); ++it) { 118 if (*it == impl) { 119 delete impl; 120 connections_.erase(it); 121 if (connections_.empty()) 122 owner_->RemoveServiceConnector(this); 123 return; 124 } 125 } 126 } 127 128 Context* context() const { return context_; } 129 130 private: 131 typedef std::vector<ServiceImpl*> ConnectionList; 132 ConnectionList connections_; 133 Context* context_; 134}; 135 136} // namespace internal 137} // namespace mojo 138 139#endif // MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_CONNECTOR_H_ 140