Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Side by Side Diff: mojo/service_manager/service_manager.cc

Issue 265793015: Mojo: Replace RemotePtr with InterfacePtr and InterfaceImpl (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 #include <stdio.h> 5 #include <stdio.h>
6 6
7 #include "mojo/service_manager/service_manager.h" 7 #include "mojo/service_manager/service_manager.h"
8 8
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/stl_util.h" 12 #include "base/stl_util.h"
13 #include "mojo/public/cpp/bindings/allocation_scope.h" 13 #include "mojo/public/cpp/bindings/allocation_scope.h"
14 #include "mojo/public/cpp/bindings/error_handler.h"
15 #include "mojo/public/cpp/bindings/remote_ptr.h"
16 #include "mojo/service_manager/service_loader.h" 14 #include "mojo/service_manager/service_loader.h"
17 15
18 namespace mojo { 16 namespace mojo {
19 17
20 namespace { 18 namespace {
21 // Used by TestAPI. 19 // Used by TestAPI.
22 bool has_created_instance = false; 20 bool has_created_instance = false;
23 } 21 }
24 22
25 class ServiceManager::ServiceFactory : public Shell, public ErrorHandler { 23 class ServiceManager::ServiceFactory : public Shell {
26 public: 24 public:
27 ServiceFactory(ServiceManager* manager, const GURL& url) 25 ServiceFactory(ServiceManager* manager, const GURL& url)
28 : manager_(manager), 26 : manager_(manager),
29 url_(url) { 27 url_(url),
30 InterfacePipe<Shell> pipe; 28 client_(NULL) {
31 shell_client_.reset(pipe.handle_to_peer.Pass(), this, this);
32 manager_->GetLoaderForURL(url)->LoadService(manager_,
33 url,
34 pipe.handle_to_self.Pass());
35 } 29 }
36 30
37 virtual ~ServiceFactory() {} 31 virtual ~ServiceFactory() {
32 if (manager_)
33 manager_->RemoveServiceFactory(this);
34 }
35
36 void Orphan() {
DaveMoore 2014/05/06 21:30:54 It can be hard to track down bugs when you can eit
darin (slow to review) 2014/05/06 21:39:11 The lifetime of the ServiceFactory is now bound to
37 manager_ = NULL;
38 }
38 39
39 void ConnectToClient(ScopedMessagePipeHandle handle) { 40 void ConnectToClient(ScopedMessagePipeHandle handle) {
40 if (handle.is_valid()) { 41 if (!handle.is_valid()) {
41 AllocationScope scope; 42 assert(false);
42 shell_client_->AcceptConnection(url_.spec(), handle.Pass()); 43 return;
43 } 44 }
45 AllocationScope scope;
46 client_->AcceptConnection(url_.spec(), handle.Pass());
44 } 47 }
45 48
49 // Shell implementation:
50
51 virtual void SetClient(ShellClient* client) OVERRIDE {
52 client_ = client;
53 }
54
55 virtual void Connect(const String& url,
56 ScopedMessagePipeHandle client_pipe) OVERRIDE {
57 if (manager_)
58 manager_->Connect(GURL(url.To<std::string>()), client_pipe.Pass());
59 }
60
61 const GURL& url() const { return url_; }
62
63 private:
64 ServiceManager* manager_;
65 const GURL url_;
66 ShellClient* client_;
67
68 DISALLOW_COPY_AND_ASSIGN(ServiceFactory);
69 };
70
71 class ServiceManager::TestAPI::TestShellConnection : public Shell {
72 public:
73 explicit TestShellConnection(ServiceManager* manager)
74 : manager_(manager),
75 client_(NULL) {
76 }
77 virtual ~TestShellConnection() {}
78
79 // Shell:
80 virtual void SetClient(ShellClient* client) OVERRIDE {
81 client_ = client;
82 }
46 virtual void Connect(const String& url, 83 virtual void Connect(const String& url,
47 ScopedMessagePipeHandle client_pipe) OVERRIDE { 84 ScopedMessagePipeHandle client_pipe) OVERRIDE {
48 manager_->Connect(GURL(url.To<std::string>()), client_pipe.Pass()); 85 manager_->Connect(GURL(url.To<std::string>()), client_pipe.Pass());
49 } 86 }
50 87
51 virtual void OnError() OVERRIDE {
52 manager_->OnServiceFactoryError(this);
53 }
54
55 const GURL& url() const { return url_; }
56
57 private:
58 ServiceManager* const manager_;
59 const GURL url_;
60 RemotePtr<ShellClient> shell_client_;
61
62 DISALLOW_COPY_AND_ASSIGN(ServiceFactory);
63 };
64
65 class ServiceManager::TestAPI::TestShellConnection
66 : public Shell,
67 public ErrorHandler {
68 public:
69 explicit TestShellConnection(ServiceManager* manager) : manager_(manager) {
70 InterfacePipe<Shell> pipe;
71 shell_client_.reset(pipe.handle_to_peer.Pass(), this, this);
72 shell_handle_ = pipe.handle_to_self.Pass();
73 }
74 virtual ~TestShellConnection() {}
75
76 ScopedShellHandle GetShellHandle() {
77 return shell_handle_.Pass();
78 }
79
80 // Shell:
81 virtual void Connect(const String& url,
82 ScopedMessagePipeHandle client_pipe) OVERRIDE {
83 manager_->Connect(GURL(url.To<std::string>()), client_pipe.Pass());
84 }
85
86 virtual void OnError() OVERRIDE {
87 }
88
89 private: 88 private:
90 ServiceManager* manager_; 89 ServiceManager* manager_;
91 RemotePtr<ShellClient> shell_client_; 90 ShellClient* client_;
92 ScopedShellHandle shell_handle_;
93 91
94 DISALLOW_COPY_AND_ASSIGN(TestShellConnection); 92 DISALLOW_COPY_AND_ASSIGN(TestShellConnection);
95 }; 93 };
96 94
97 // static 95 // static
98 ServiceManager::TestAPI::TestAPI(ServiceManager* manager) : manager_(manager) { 96 ServiceManager::TestAPI::TestAPI(ServiceManager* manager) : manager_(manager) {
99 } 97 }
100 98
101 ServiceManager::TestAPI::~TestAPI() { 99 ServiceManager::TestAPI::~TestAPI() {
102 } 100 }
103 101
104 bool ServiceManager::TestAPI::HasCreatedInstance() { 102 bool ServiceManager::TestAPI::HasCreatedInstance() {
105 return has_created_instance; 103 return has_created_instance;
106 } 104 }
107 105
108 ScopedShellHandle ServiceManager::TestAPI::GetShellHandle() { 106 ScopedMessagePipeHandle ServiceManager::TestAPI::GetShellHandle() {
109 if (!shell_connection_.get()) 107 MessagePipe pipe;
110 shell_connection_.reset(new TestShellConnection(manager_)); 108 shell_.Bind(new TestShellConnection(manager_));
111 return shell_connection_->GetShellHandle().Pass(); 109 shell_.ConfigureStub(pipe.handle0.Pass());
110 return pipe.handle1.Pass();
112 } 111 }
113 112
114 bool ServiceManager::TestAPI::HasFactoryForURL(const GURL& url) const { 113 bool ServiceManager::TestAPI::HasFactoryForURL(const GURL& url) const {
115 return manager_->url_to_service_factory_.find(url) != 114 return manager_->url_to_service_factory_.find(url) !=
116 manager_->url_to_service_factory_.end(); 115 manager_->url_to_service_factory_.end();
117 } 116 }
118 117
119 ServiceManager::ServiceManager() 118 ServiceManager::ServiceManager()
120 : interceptor_(NULL) { 119 : interceptor_(NULL) {
121 } 120 }
122 121
123 ServiceManager::~ServiceManager() { 122 ServiceManager::~ServiceManager() {
124 STLDeleteValues(&url_to_service_factory_); 123 // Make sure any lingering service factories no longer reference us.
124 for (URLToServiceFactoryMap::iterator it = url_to_service_factory_.begin();
125 it != url_to_service_factory_.end(); ++it) {
126 it->second->Orphan();
127 }
128
125 STLDeleteValues(&url_to_loader_); 129 STLDeleteValues(&url_to_loader_);
126 STLDeleteValues(&scheme_to_loader_); 130 STLDeleteValues(&scheme_to_loader_);
127 } 131 }
128 132
129 // static 133 // static
130 ServiceManager* ServiceManager::GetInstance() { 134 ServiceManager* ServiceManager::GetInstance() {
131 static base::LazyInstance<ServiceManager> instance = 135 static base::LazyInstance<ServiceManager> instance =
132 LAZY_INSTANCE_INITIALIZER; 136 LAZY_INSTANCE_INITIALIZER;
133 has_created_instance = true; 137 has_created_instance = true;
134 return &instance.Get(); 138 return &instance.Get();
135 } 139 }
136 140
137 void ServiceManager::Connect(const GURL& url, 141 void ServiceManager::Connect(const GURL& url,
138 ScopedMessagePipeHandle client_handle) { 142 ScopedMessagePipeHandle client_handle) {
139 URLToServiceFactoryMap::const_iterator service_it = 143 URLToServiceFactoryMap::const_iterator service_it =
140 url_to_service_factory_.find(url); 144 url_to_service_factory_.find(url);
141 ServiceFactory* service_factory; 145 ServiceFactory* service_factory;
142 if (service_it != url_to_service_factory_.end()) { 146 if (service_it != url_to_service_factory_.end()) {
143 service_factory = service_it->second; 147 service_factory = service_it->second;
144 } else { 148 } else {
145 service_factory = new ServiceFactory(this, url); 149 service_factory = new ServiceFactory(this, url);
150
151 GetLoaderForURL(url)->LoadService(
152 this, url, BindToPipe<Shell>(service_factory).Pass());
153
154 // NOTE: The lifetime of the service_factory instance is now bound to the
155 // MessagePipe passed to LoadService. We retain a raw pointer to
156 // service_factory so that we can continue communicating with it.
157
146 url_to_service_factory_[url] = service_factory; 158 url_to_service_factory_[url] = service_factory;
147 } 159 }
148 if (interceptor_) { 160 if (interceptor_) {
149 service_factory->ConnectToClient( 161 service_factory->ConnectToClient(
150 interceptor_->OnConnectToClient(url, client_handle.Pass())); 162 interceptor_->OnConnectToClient(url, client_handle.Pass()));
151 } else { 163 } else {
152 service_factory->ConnectToClient(client_handle.Pass()); 164 service_factory->ConnectToClient(client_handle.Pass());
153 } 165 }
154 } 166 }
155 167
(...skipping 22 matching lines...) Expand all
178 if (url_it != url_to_loader_.end()) 190 if (url_it != url_to_loader_.end())
179 return url_it->second; 191 return url_it->second;
180 SchemeToLoaderMap::const_iterator scheme_it = 192 SchemeToLoaderMap::const_iterator scheme_it =
181 scheme_to_loader_.find(url.scheme()); 193 scheme_to_loader_.find(url.scheme());
182 if (scheme_it != scheme_to_loader_.end()) 194 if (scheme_it != scheme_to_loader_.end())
183 return scheme_it->second; 195 return scheme_it->second;
184 DCHECK(default_loader_); 196 DCHECK(default_loader_);
185 return default_loader_.get(); 197 return default_loader_.get();
186 } 198 }
187 199
188 void ServiceManager::OnServiceFactoryError(ServiceFactory* service_factory) { 200 void ServiceManager::RemoveServiceFactory(ServiceFactory* service_factory) {
DaveMoore 2014/05/06 21:30:54 This is called OnServiceFactoryError() because it
darin (slow to review) 2014/05/06 21:39:11 I just had service.h on the mind. Renamed back to
189 const GURL url = service_factory->url(); 201 const GURL url = service_factory->url();
190 URLToServiceFactoryMap::iterator it = url_to_service_factory_.find(url); 202 URLToServiceFactoryMap::iterator it = url_to_service_factory_.find(url);
191 DCHECK(it != url_to_service_factory_.end()); 203 DCHECK(it != url_to_service_factory_.end());
192 delete it->second;
193 url_to_service_factory_.erase(it); 204 url_to_service_factory_.erase(it);
194 GetLoaderForURL(url)->OnServiceError(this, url); 205 GetLoaderForURL(url)->OnServiceError(this, url);
195 } 206 }
196 207
197 } // namespace mojo 208 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698