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

Side by Side Diff: content/common/service_manager/service_manager_connection_impl.cc

Issue 2729733003: Change ServiceManagerConnectionImpl to run service request handlers on the IO thread. (Closed)
Patch Set: Fix startup race. Created 3 years, 9 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "content/common/service_manager/service_manager_connection_impl.h" 5 #include "content/common/service_manager/service_manager_connection_impl.h"
6 6
7 #include <queue> 7 #include <queue>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 // bindings. 42 // bindings.
43 class ServiceManagerConnectionImpl::IOThreadContext 43 class ServiceManagerConnectionImpl::IOThreadContext
44 : public base::RefCountedThreadSafe<IOThreadContext>, 44 : public base::RefCountedThreadSafe<IOThreadContext>,
45 public service_manager::Service, 45 public service_manager::Service,
46 public service_manager::InterfaceFactory< 46 public service_manager::InterfaceFactory<
47 service_manager::mojom::ServiceFactory>, 47 service_manager::mojom::ServiceFactory>,
48 public service_manager::mojom::ServiceFactory { 48 public service_manager::mojom::ServiceFactory {
49 public: 49 public:
50 using InitializeCallback = 50 using InitializeCallback =
51 base::Callback<void(const service_manager::Identity&)>; 51 base::Callback<void(const service_manager::Identity&)>;
52 using ServiceFactoryCallback =
53 base::Callback<void(service_manager::mojom::ServiceRequest,
54 const std::string&)>;
55 52
56 IOThreadContext( 53 IOThreadContext(
57 service_manager::mojom::ServiceRequest service_request, 54 service_manager::mojom::ServiceRequest service_request,
58 scoped_refptr<base::SequencedTaskRunner> io_task_runner, 55 scoped_refptr<base::SequencedTaskRunner> io_task_runner,
59 std::unique_ptr<service_manager::Connector> io_thread_connector, 56 std::unique_ptr<service_manager::Connector> io_thread_connector,
60 service_manager::mojom::ConnectorRequest connector_request) 57 service_manager::mojom::ConnectorRequest connector_request)
61 : pending_service_request_(std::move(service_request)), 58 : pending_service_request_(std::move(service_request)),
62 io_task_runner_(io_task_runner), 59 io_task_runner_(io_task_runner),
63 io_thread_connector_(std::move(io_thread_connector)), 60 io_thread_connector_(std::move(io_thread_connector)),
64 pending_connector_request_(std::move(connector_request)), 61 pending_connector_request_(std::move(connector_request)),
65 weak_factory_(this) { 62 weak_factory_(this) {
66 // This will be reattached by any of the IO thread functions on first call. 63 // This will be reattached by any of the IO thread functions on first call.
67 io_thread_checker_.DetachFromThread(); 64 io_thread_checker_.DetachFromThread();
68 } 65 }
69 66
70 // Safe to call from any thread. 67 // Safe to call from any thread.
71 void Start( 68 void Start(
72 const InitializeCallback& initialize_callback, 69 const InitializeCallback& initialize_callback,
73 const ServiceManagerConnection::OnConnectHandler& on_connect_callback, 70 const ServiceManagerConnection::OnConnectHandler& on_connect_callback,
74 const ServiceFactoryCallback& create_service_callback,
75 const base::Closure& stop_callback) { 71 const base::Closure& stop_callback) {
76 DCHECK(!started_); 72 DCHECK(!started_);
77 73
78 started_ = true; 74 started_ = true;
79 callback_task_runner_ = base::ThreadTaskRunnerHandle::Get(); 75 callback_task_runner_ = base::ThreadTaskRunnerHandle::Get();
80 initialize_handler_ = initialize_callback; 76 initialize_handler_ = initialize_callback;
81 on_connect_callback_ = on_connect_callback; 77 on_connect_callback_ = on_connect_callback;
82 create_service_callback_ = create_service_callback;
83 stop_callback_ = stop_callback; 78 stop_callback_ = stop_callback;
84 io_task_runner_->PostTask( 79 io_task_runner_->PostTask(
85 FROM_HERE, base::Bind(&IOThreadContext::StartOnIOThread, this)); 80 FROM_HERE, base::Bind(&IOThreadContext::StartOnIOThread, this));
86 } 81 }
87 82
88 // Safe to call from whichever thread called Start() (or may have called 83 // Safe to call from whichever thread called Start() (or may have called
89 // Start()). Must be called before IO thread shutdown. 84 // Start()). Must be called before IO thread shutdown.
90 void ShutDown() { 85 void ShutDown() {
91 if (!started_) 86 if (!started_)
92 return; 87 return;
(...skipping 26 matching lines...) Expand all
119 114
120 // Safe to call any time before Start() is called. 115 // Safe to call any time before Start() is called.
121 void SetDefaultBinderForBrowserConnection( 116 void SetDefaultBinderForBrowserConnection(
122 const service_manager::InterfaceRegistry::Binder& binder) { 117 const service_manager::InterfaceRegistry::Binder& binder) {
123 DCHECK(!started_); 118 DCHECK(!started_);
124 default_browser_binder_ = base::Bind( 119 default_browser_binder_ = base::Bind(
125 &IOThreadContext::CallBinderOnTaskRunner, 120 &IOThreadContext::CallBinderOnTaskRunner,
126 base::ThreadTaskRunnerHandle::Get(), binder); 121 base::ThreadTaskRunnerHandle::Get(), binder);
127 } 122 }
128 123
124 void AddEmbeddedService(const std::string& name, const ServiceInfo& info) {
125 io_task_runner_->PostTask(
126 FROM_HERE, base::Bind(&ServiceManagerConnectionImpl::IOThreadContext::
127 AddEmbeddedServiceRequestHandlerOnIoThread,
128 this, name, info));
129 }
130
131 void AddServiceRequestHandler(const std::string& name,
132 const ServiceRequestHandler& handler) {
133 io_task_runner_->PostTask(
134 FROM_HERE, base::Bind(&ServiceManagerConnectionImpl::IOThreadContext::
135 AddServiceRequestHandlerOnIoThread,
136 this, name, handler));
137 }
138
129 private: 139 private:
130 friend class base::RefCountedThreadSafe<IOThreadContext>; 140 friend class base::RefCountedThreadSafe<IOThreadContext>;
131 141
132 class MessageLoopObserver : public base::MessageLoop::DestructionObserver { 142 class MessageLoopObserver : public base::MessageLoop::DestructionObserver {
133 public: 143 public:
134 explicit MessageLoopObserver(base::WeakPtr<IOThreadContext> context) 144 explicit MessageLoopObserver(base::WeakPtr<IOThreadContext> context)
135 : context_(context) { 145 : context_(context) {
136 base::MessageLoop::current()->AddDestructionObserver(this); 146 base::MessageLoop::current()->AddDestructionObserver(this);
137 } 147 }
138 148
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 206
197 // Resetting the ServiceContext below may otherwise release the last 207 // Resetting the ServiceContext below may otherwise release the last
198 // reference to this IOThreadContext. We keep it alive until the stack 208 // reference to this IOThreadContext. We keep it alive until the stack
199 // unwinds. 209 // unwinds.
200 scoped_refptr<IOThreadContext> keepalive(this); 210 scoped_refptr<IOThreadContext> keepalive(this);
201 211
202 factory_bindings_.CloseAllBindings(); 212 factory_bindings_.CloseAllBindings();
203 service_context_.reset(); 213 service_context_.reset();
204 214
205 ClearConnectionFiltersOnIOThread(); 215 ClearConnectionFiltersOnIOThread();
216
217 request_handlers_.clear();
218 embedded_services_.clear();
206 } 219 }
207 220
208 void ClearConnectionFiltersOnIOThread() { 221 void ClearConnectionFiltersOnIOThread() {
209 base::AutoLock lock(lock_); 222 base::AutoLock lock(lock_);
210 connection_filters_.clear(); 223 connection_filters_.clear();
211 } 224 }
212 225
213 void RemoveConnectionFilterOnIOThread(int filter_id) { 226 void RemoveConnectionFilterOnIOThread(int filter_id) {
214 base::AutoLock lock(lock_); 227 base::AutoLock lock(lock_);
215 auto it = connection_filters_.find(filter_id); 228 auto it = connection_filters_.find(filter_id);
216 // During shutdown the connection filters might have been cleared already 229 // During shutdown the connection filters might have been cleared already
217 // by ClearConnectionFiltersOnIOThread() above, so this id might not exist. 230 // by ClearConnectionFiltersOnIOThread() above, so this id might not exist.
218 if (it != connection_filters_.end()) 231 if (it != connection_filters_.end())
219 connection_filters_.erase(it); 232 connection_filters_.erase(it);
220 } 233 }
221 234
222 void OnBrowserConnectionLost() { 235 void OnBrowserConnectionLost() {
223 DCHECK(io_thread_checker_.CalledOnValidThread()); 236 DCHECK(io_thread_checker_.CalledOnValidThread());
224 has_browser_connection_ = false; 237 has_browser_connection_ = false;
225 } 238 }
226 239
240 void AddEmbeddedServiceRequestHandlerOnIoThread(const std::string& name,
241 const ServiceInfo& info) {
242 DCHECK(io_thread_checker_.CalledOnValidThread());
243 std::unique_ptr<EmbeddedServiceRunner> service(
244 new EmbeddedServiceRunner(name, info));
245 AddServiceRequestHandlerOnIoThread(
246 name, base::Bind(&EmbeddedServiceRunner::BindServiceRequest,
247 base::Unretained(service.get())));
248 auto result =
249 embedded_services_.insert(std::make_pair(name, std::move(service)));
250 DCHECK(result.second);
251 }
252
253 void AddServiceRequestHandlerOnIoThread(
254 const std::string& name,
255 const ServiceRequestHandler& handler) {
256 DCHECK(io_thread_checker_.CalledOnValidThread());
257 auto result = request_handlers_.insert(std::make_pair(name, handler));
258 DCHECK(result.second);
259 }
260
227 ///////////////////////////////////////////////////////////////////////////// 261 /////////////////////////////////////////////////////////////////////////////
228 // service_manager::Service implementation 262 // service_manager::Service implementation
229 263
230 void OnStart() override { 264 void OnStart() override {
231 DCHECK(io_thread_checker_.CalledOnValidThread()); 265 DCHECK(io_thread_checker_.CalledOnValidThread());
232 DCHECK(!initialize_handler_.is_null()); 266 DCHECK(!initialize_handler_.is_null());
233 local_info_ = context()->local_info(); 267 local_info_ = context()->local_info();
234 268
235 InitializeCallback handler = base::ResetAndReturn(&initialize_handler_); 269 InitializeCallback handler = base::ResetAndReturn(&initialize_handler_);
236 callback_task_runner_->PostTask(FROM_HERE, 270 callback_task_runner_->PostTask(FROM_HERE,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 DCHECK(io_thread_checker_.CalledOnValidThread()); 322 DCHECK(io_thread_checker_.CalledOnValidThread());
289 factory_bindings_.AddBinding(this, std::move(request)); 323 factory_bindings_.AddBinding(this, std::move(request));
290 } 324 }
291 325
292 ///////////////////////////////////////////////////////////////////////////// 326 /////////////////////////////////////////////////////////////////////////////
293 // service_manager::mojom::ServiceFactory implementation 327 // service_manager::mojom::ServiceFactory implementation
294 328
295 void CreateService(service_manager::mojom::ServiceRequest request, 329 void CreateService(service_manager::mojom::ServiceRequest request,
296 const std::string& name) override { 330 const std::string& name) override {
297 DCHECK(io_thread_checker_.CalledOnValidThread()); 331 DCHECK(io_thread_checker_.CalledOnValidThread());
298 callback_task_runner_->PostTask( 332 auto it = request_handlers_.find(name);
299 FROM_HERE, 333 DCHECK(it != request_handlers_.end())
300 base::Bind(create_service_callback_, base::Passed(&request), name)); 334 << "Can't create service " << name << ". No handler found.";
335 it->second.Run(std::move(request));
301 } 336 }
302 337
303 static void CallBinderOnTaskRunner( 338 static void CallBinderOnTaskRunner(
304 scoped_refptr<base::SequencedTaskRunner> task_runner, 339 scoped_refptr<base::SequencedTaskRunner> task_runner,
305 const service_manager::InterfaceRegistry::Binder& binder, 340 const service_manager::InterfaceRegistry::Binder& binder,
306 const std::string& interface_name, 341 const std::string& interface_name,
307 mojo::ScopedMessagePipeHandle request_handle) { 342 mojo::ScopedMessagePipeHandle request_handle) {
308 task_runner->PostTask(FROM_HERE, base::Bind(binder, interface_name, 343 task_runner->PostTask(FROM_HERE, base::Bind(binder, interface_name,
309 base::Passed(&request_handle))); 344 base::Passed(&request_handle)));
310 } 345 }
(...skipping 11 matching lines...) Expand all
322 // TaskRunner on which to run our owner's callbacks, i.e. the ones passed to 357 // TaskRunner on which to run our owner's callbacks, i.e. the ones passed to
323 // Start(). 358 // Start().
324 scoped_refptr<base::SequencedTaskRunner> callback_task_runner_; 359 scoped_refptr<base::SequencedTaskRunner> callback_task_runner_;
325 360
326 // Callback to run once Service::OnStart is invoked. 361 // Callback to run once Service::OnStart is invoked.
327 InitializeCallback initialize_handler_; 362 InitializeCallback initialize_handler_;
328 363
329 // Callback to run when a connection request is received. 364 // Callback to run when a connection request is received.
330 ServiceManagerConnection::OnConnectHandler on_connect_callback_; 365 ServiceManagerConnection::OnConnectHandler on_connect_callback_;
331 366
332 // Callback to run when a new Service request is received.
333 ServiceFactoryCallback create_service_callback_;
334
335 // Callback to run if the service is stopped by the service manager. 367 // Callback to run if the service is stopped by the service manager.
336 base::Closure stop_callback_; 368 base::Closure stop_callback_;
337 369
338 // Called once a connection has been received from the browser process & the 370 // Called once a connection has been received from the browser process & the
339 // default binder (below) has been set up. 371 // default binder (below) has been set up.
340 bool has_browser_connection_ = false; 372 bool has_browser_connection_ = false;
341 373
342 service_manager::ServiceInfo local_info_; 374 service_manager::ServiceInfo local_info_;
343 375
344 // Default binder callback used for the browser connection's 376 // Default binder callback used for the browser connection's
345 // InterfaceRegistry. 377 // InterfaceRegistry.
346 // 378 //
347 // TODO(rockot): Remove this once all interfaces exposed to the browser are 379 // TODO(rockot): Remove this once all interfaces exposed to the browser are
348 // exposed via a ConnectionFilter. 380 // exposed via a ConnectionFilter.
349 service_manager::InterfaceRegistry::Binder default_browser_binder_; 381 service_manager::InterfaceRegistry::Binder default_browser_binder_;
350 382
351 std::unique_ptr<service_manager::ServiceContext> service_context_; 383 std::unique_ptr<service_manager::ServiceContext> service_context_;
352 mojo::BindingSet<service_manager::mojom::ServiceFactory> factory_bindings_; 384 mojo::BindingSet<service_manager::mojom::ServiceFactory> factory_bindings_;
353 int next_filter_id_ = kInvalidConnectionFilterId; 385 int next_filter_id_ = kInvalidConnectionFilterId;
354 386
355 // Not owned. 387 // Not owned.
356 MessageLoopObserver* message_loop_observer_ = nullptr; 388 MessageLoopObserver* message_loop_observer_ = nullptr;
357 389
358 // Guards |connection_filters_|. 390 // Guards |connection_filters_|.
359 base::Lock lock_; 391 base::Lock lock_;
360 std::map<int, std::unique_ptr<ConnectionFilter>> connection_filters_; 392 std::map<int, std::unique_ptr<ConnectionFilter>> connection_filters_;
361 393
394 std::unordered_map<std::string, std::unique_ptr<EmbeddedServiceRunner>>
395 embedded_services_;
396 std::unordered_map<std::string, ServiceRequestHandler> request_handlers_;
397
362 base::WeakPtrFactory<IOThreadContext> weak_factory_; 398 base::WeakPtrFactory<IOThreadContext> weak_factory_;
363 399
364 DISALLOW_COPY_AND_ASSIGN(IOThreadContext); 400 DISALLOW_COPY_AND_ASSIGN(IOThreadContext);
365 }; 401 };
366 402
367 //////////////////////////////////////////////////////////////////////////////// 403 ////////////////////////////////////////////////////////////////////////////////
368 // ServiceManagerConnection, public: 404 // ServiceManagerConnection, public:
369 405
370 // static 406 // static
371 void ServiceManagerConnection::SetForProcess( 407 void ServiceManagerConnection::SetForProcess(
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 462
427 //////////////////////////////////////////////////////////////////////////////// 463 ////////////////////////////////////////////////////////////////////////////////
428 // ServiceManagerConnectionImpl, ServiceManagerConnection implementation: 464 // ServiceManagerConnectionImpl, ServiceManagerConnection implementation:
429 465
430 void ServiceManagerConnectionImpl::Start() { 466 void ServiceManagerConnectionImpl::Start() {
431 context_->Start( 467 context_->Start(
432 base::Bind(&ServiceManagerConnectionImpl::OnContextInitialized, 468 base::Bind(&ServiceManagerConnectionImpl::OnContextInitialized,
433 weak_factory_.GetWeakPtr()), 469 weak_factory_.GetWeakPtr()),
434 base::Bind(&ServiceManagerConnectionImpl::OnConnect, 470 base::Bind(&ServiceManagerConnectionImpl::OnConnect,
435 weak_factory_.GetWeakPtr()), 471 weak_factory_.GetWeakPtr()),
436 base::Bind(&ServiceManagerConnectionImpl::CreateService,
437 weak_factory_.GetWeakPtr()),
438 base::Bind(&ServiceManagerConnectionImpl::OnConnectionLost, 472 base::Bind(&ServiceManagerConnectionImpl::OnConnectionLost,
439 weak_factory_.GetWeakPtr())); 473 weak_factory_.GetWeakPtr()));
440 } 474 }
441 475
442 service_manager::Connector* ServiceManagerConnectionImpl::GetConnector() { 476 service_manager::Connector* ServiceManagerConnectionImpl::GetConnector() {
443 return connector_.get(); 477 return connector_.get();
444 } 478 }
445 479
446 const service_manager::Identity& ServiceManagerConnectionImpl::GetIdentity() 480 const service_manager::Identity& ServiceManagerConnectionImpl::GetIdentity()
447 const { 481 const {
(...skipping 21 matching lines...) Expand all
469 std::unique_ptr<ConnectionFilter> filter) { 503 std::unique_ptr<ConnectionFilter> filter) {
470 return context_->AddConnectionFilter(std::move(filter)); 504 return context_->AddConnectionFilter(std::move(filter));
471 } 505 }
472 506
473 void ServiceManagerConnectionImpl::RemoveConnectionFilter(int filter_id) { 507 void ServiceManagerConnectionImpl::RemoveConnectionFilter(int filter_id) {
474 context_->RemoveConnectionFilter(filter_id); 508 context_->RemoveConnectionFilter(filter_id);
475 } 509 }
476 510
477 void ServiceManagerConnectionImpl::AddEmbeddedService(const std::string& name, 511 void ServiceManagerConnectionImpl::AddEmbeddedService(const std::string& name,
478 const ServiceInfo& info) { 512 const ServiceInfo& info) {
479 std::unique_ptr<EmbeddedServiceRunner> service( 513 context_->AddEmbeddedService(name, info);
480 new EmbeddedServiceRunner(name, info));
481 AddServiceRequestHandler(
482 name, base::Bind(&EmbeddedServiceRunner::BindServiceRequest,
483 base::Unretained(service.get())));
484 auto result =
485 embedded_services_.insert(std::make_pair(name, std::move(service)));
486 DCHECK(result.second);
487 } 514 }
488 515
489 void ServiceManagerConnectionImpl::AddServiceRequestHandler( 516 void ServiceManagerConnectionImpl::AddServiceRequestHandler(
490 const std::string& name, 517 const std::string& name,
491 const ServiceRequestHandler& handler) { 518 const ServiceRequestHandler& handler) {
492 auto result = request_handlers_.insert(std::make_pair(name, handler)); 519 context_->AddServiceRequestHandler(name, handler);
493 DCHECK(result.second);
494 } 520 }
495 521
496 int ServiceManagerConnectionImpl::AddOnConnectHandler( 522 int ServiceManagerConnectionImpl::AddOnConnectHandler(
497 const OnConnectHandler& handler) { 523 const OnConnectHandler& handler) {
498 int id = ++next_on_connect_handler_id_; 524 int id = ++next_on_connect_handler_id_;
499 on_connect_handlers_[id] = handler; 525 on_connect_handlers_[id] = handler;
500 return id; 526 return id;
501 } 527 }
502 528
503 void ServiceManagerConnectionImpl::RemoveOnConnectHandler(int id) { 529 void ServiceManagerConnectionImpl::RemoveOnConnectHandler(int id) {
504 auto it = on_connect_handlers_.find(id); 530 auto it = on_connect_handlers_.find(id);
505 DCHECK(it != on_connect_handlers_.end()); 531 DCHECK(it != on_connect_handlers_.end());
506 on_connect_handlers_.erase(it); 532 on_connect_handlers_.erase(it);
507 } 533 }
508 534
509 void ServiceManagerConnectionImpl::CreateService(
510 service_manager::mojom::ServiceRequest request,
511 const std::string& name) {
512 auto it = request_handlers_.find(name);
513 DCHECK(it != request_handlers_.end())
514 << "Can't create service " << name << ". No handler found.";
515 if (it != request_handlers_.end())
516 it->second.Run(std::move(request));
517 }
518
519 void ServiceManagerConnectionImpl::OnContextInitialized( 535 void ServiceManagerConnectionImpl::OnContextInitialized(
520 const service_manager::Identity& identity) { 536 const service_manager::Identity& identity) {
521 identity_ = identity; 537 identity_ = identity;
522 } 538 }
523 539
524 void ServiceManagerConnectionImpl::OnConnectionLost() { 540 void ServiceManagerConnectionImpl::OnConnectionLost() {
525 if (!connection_lost_handler_.is_null()) 541 if (!connection_lost_handler_.is_null())
526 connection_lost_handler_.Run(); 542 connection_lost_handler_.Run();
527 } 543 }
528 544
529 void ServiceManagerConnectionImpl::OnConnect( 545 void ServiceManagerConnectionImpl::OnConnect(
530 const service_manager::ServiceInfo& local_info, 546 const service_manager::ServiceInfo& local_info,
531 const service_manager::ServiceInfo& remote_info) { 547 const service_manager::ServiceInfo& remote_info) {
532 local_info_ = local_info; 548 local_info_ = local_info;
533 for (auto& handler : on_connect_handlers_) 549 for (auto& handler : on_connect_handlers_)
534 handler.second.Run(local_info, remote_info); 550 handler.second.Run(local_info, remote_info);
535 } 551 }
536 552
537 void ServiceManagerConnectionImpl::GetInterface( 553 void ServiceManagerConnectionImpl::GetInterface(
538 service_manager::mojom::InterfaceProvider* provider, 554 service_manager::mojom::InterfaceProvider* provider,
539 const std::string& interface_name, 555 const std::string& interface_name,
540 mojo::ScopedMessagePipeHandle request_handle) { 556 mojo::ScopedMessagePipeHandle request_handle) {
541 provider->GetInterface(interface_name, std::move(request_handle)); 557 provider->GetInterface(interface_name, std::move(request_handle));
542 } 558 }
543 559
544 } // namespace content 560 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698