OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef MOJO_PUBLIC_SHELL_SERVICE_H_ | 5 #ifndef MOJO_PUBLIC_SHELL_SERVICE_H_ |
6 #define MOJO_PUBLIC_SHELL_SERVICE_H_ | 6 #define MOJO_PUBLIC_SHELL_SERVICE_H_ |
7 | 7 |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "mojo/public/bindings/error_handler.h" | 10 #include "mojo/public/bindings/error_handler.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 // Context: Optional type of shared context.v | 51 // Context: Optional type of shared context.v |
52 namespace mojo { | 52 namespace mojo { |
53 | 53 |
54 class ServiceFactoryBase : public ShellClient { | 54 class ServiceFactoryBase : public ShellClient { |
55 public: | 55 public: |
56 virtual ~ServiceFactoryBase(); | 56 virtual ~ServiceFactoryBase(); |
57 | 57 |
58 protected: | 58 protected: |
59 ServiceFactoryBase(ScopedMessagePipeHandle shell_handle); | 59 ServiceFactoryBase(ScopedMessagePipeHandle shell_handle); |
60 Shell* shell() { return shell_.get(); } | 60 Shell* shell() { return shell_.get(); } |
| 61 // Destroys connection to Shell. |
| 62 void DisconnectFromShell(); |
61 | 63 |
62 private: | 64 private: |
63 RemotePtr<Shell> shell_; | 65 RemotePtr<Shell> shell_; |
64 }; | 66 }; |
65 | 67 |
66 template <class ServiceImpl, typename Context=void> | 68 template <class ServiceImpl, typename Context=void> |
67 class ServiceFactory : public ServiceFactoryBase { | 69 class ServiceFactory : public ServiceFactoryBase { |
68 public: | 70 public: |
69 ServiceFactory(ScopedMessagePipeHandle shell_handle, Context* context = NULL) | 71 ServiceFactory(ScopedMessagePipeHandle shell_handle, Context* context = NULL) |
70 : ServiceFactoryBase(shell_handle.Pass()), | 72 : ServiceFactoryBase(shell_handle.Pass()), |
(...skipping 10 matching lines...) Expand all Loading... |
81 ServiceImpl* service = new ServiceImpl(); | 83 ServiceImpl* service = new ServiceImpl(); |
82 service->Initialize(this, client_handle.Pass()); | 84 service->Initialize(this, client_handle.Pass()); |
83 services_.push_back(service); | 85 services_.push_back(service); |
84 } | 86 } |
85 | 87 |
86 void RemoveService(ServiceImpl* service) { | 88 void RemoveService(ServiceImpl* service) { |
87 for (typename ServiceList::iterator it = services_.begin(); | 89 for (typename ServiceList::iterator it = services_.begin(); |
88 it != services_.end(); ++it) { | 90 it != services_.end(); ++it) { |
89 if (*it == service) { | 91 if (*it == service) { |
90 services_.erase(it); | 92 services_.erase(it); |
| 93 if (services_.empty()) |
| 94 DisconnectFromShell(); |
91 return; | 95 return; |
92 } | 96 } |
93 } | 97 } |
94 } | 98 } |
95 | 99 |
96 Context* context() const { | 100 Context* context() const { |
97 return context_; | 101 return context_; |
98 } | 102 } |
99 | 103 |
100 private: | 104 private: |
101 typedef std::vector<ServiceImpl*> ServiceList; | 105 typedef std::vector<ServiceImpl*> ServiceList; |
102 ServiceList services_; | 106 ServiceList services_; |
103 Context* context_; | 107 Context* context_; |
104 }; | 108 }; |
105 | 109 |
106 // Specialization of ServiceFactory. | 110 // Specialization of ServiceFactory. |
107 // ServiceInterface: Service interface. | 111 // ServiceInterface: Service interface. |
108 // ServiceImpl: Implementation of Service interface. | 112 // ServiceImpl: Implementation of Service interface. |
109 // Context: Optional type of shared context. | 113 // Context: Optional type of shared context. |
110 template <class ServiceInterface, class ServiceImpl, typename Context=void> | 114 template <class ServiceInterface, class ServiceImpl, typename Context=void> |
111 class Service : public ServiceInterface { | 115 class Service : public ServiceInterface { |
112 public: | 116 public: |
113 virtual ~Service() { | 117 virtual ~Service() { |
114 service_factory_->RemoveService(static_cast<ServiceImpl*>(this)); | 118 service_factory_->RemoveService(static_cast<ServiceImpl*>(this)); |
115 } | 119 } |
116 | 120 |
117 protected: | 121 protected: |
118 friend class ServiceFactory<ServiceImpl, Context>; | 122 friend class ServiceFactory<ServiceImpl, Context>; |
119 Service() {} | 123 Service() : reaper_(this) {} |
120 | 124 |
121 void Initialize(ServiceFactory<ServiceImpl, Context>* service_factory, | 125 void Initialize(ServiceFactory<ServiceImpl, Context>* service_factory, |
122 ScopedMessagePipeHandle client_handle) { | 126 ScopedMessagePipeHandle client_handle) { |
123 service_factory_ = service_factory; | 127 service_factory_ = service_factory; |
124 client_.reset(client_handle.Pass(), this); | 128 client_.reset(client_handle.Pass(), this, &reaper_); |
125 } | 129 } |
126 | 130 |
127 Context* context() const { | 131 Context* context() const { |
128 return service_factory_->context(); | 132 return service_factory_->context(); |
129 } | 133 } |
130 | 134 |
131 typename ServiceInterface::_Peer* client() { return client_.get(); } | 135 typename ServiceInterface::_Peer* client() { return client_.get(); } |
132 | 136 |
133 private: | 137 private: |
| 138 // The Reaper class allows us to handle errors on the client proxy without |
| 139 // polluting the name space of the Service<> class. |
| 140 class Reaper : public ErrorHandler { |
| 141 public: |
| 142 Reaper(Service<ServiceInterface, ServiceImpl, Context>* service) |
| 143 : service_(service) {} |
| 144 virtual void OnError() { |
| 145 delete service_; |
| 146 } |
| 147 private: |
| 148 Service<ServiceInterface, ServiceImpl, Context>* service_; |
| 149 }; |
| 150 Reaper reaper_; |
134 ServiceFactory<ServiceImpl, Context>* service_factory_; | 151 ServiceFactory<ServiceImpl, Context>* service_factory_; |
135 RemotePtr<typename ServiceInterface::_Peer> client_; | 152 RemotePtr<typename ServiceInterface::_Peer> client_; |
136 }; | 153 }; |
137 | 154 |
138 } // namespace mojo | 155 } // namespace mojo |
139 | 156 |
140 #endif // MOJO_PUBLIC_SHELL_SERVICE_H_ | 157 #endif // MOJO_PUBLIC_SHELL_SERVICE_H_ |
OLD | NEW |