jankometer: Remove.
[chromium-blink-merge.git] / mojo / service_manager / background_shell_service_loader.cc
blobef97255f283cc87fde323d617f9c6473890263a3
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.
5 #include "mojo/service_manager/background_shell_service_loader.h"
7 #include "base/bind.h"
8 #include "base/run_loop.h"
9 #include "mojo/service_manager/service_manager.h"
11 namespace mojo {
13 class BackgroundShellServiceLoader::BackgroundLoader {
14 public:
15 explicit BackgroundLoader(ServiceLoader* loader) : loader_(loader) {}
16 ~BackgroundLoader() {}
18 void LoadService(ServiceManager* manager,
19 const GURL& url,
20 ScopedMessagePipeHandle shell_handle) {
21 loader_->LoadService(manager, url, shell_handle.Pass());
24 void OnServiceError(ServiceManager* manager, const GURL& url) {
25 loader_->OnServiceError(manager, url);
28 private:
29 ServiceLoader* loader_; // Owned by BackgroundShellServiceLoader
31 DISALLOW_COPY_AND_ASSIGN(BackgroundLoader);
34 BackgroundShellServiceLoader::BackgroundShellServiceLoader(
35 scoped_ptr<ServiceLoader> real_loader,
36 const std::string& thread_name,
37 base::MessageLoop::Type message_loop_type)
38 : loader_(real_loader.Pass()),
39 message_loop_type_(message_loop_type),
40 thread_name_(thread_name),
41 message_loop_created_(true, false),
42 background_loader_(NULL) {
45 BackgroundShellServiceLoader::~BackgroundShellServiceLoader() {
46 if (thread_)
47 thread_->Join();
50 void BackgroundShellServiceLoader::LoadService(
51 ServiceManager* manager,
52 const GURL& url,
53 ScopedMessagePipeHandle shell_handle) {
54 if (!thread_) {
55 // TODO(tim): It'd be nice if we could just have each LoadService call
56 // result in a new thread like DynamicService{Loader, Runner}. But some
57 // loaders are creating multiple ApplicationImpls (NetworkServiceLoader)
58 // sharing a delegate (etc). So we have to keep it single threaded, wait
59 // for the thread to initialize, and post to the TaskRunner for subsequent
60 // LoadService calls for now.
61 thread_.reset(new base::DelegateSimpleThread(this, thread_name_));
62 thread_->Start();
63 message_loop_created_.Wait();
64 DCHECK(task_runner_);
67 task_runner_->PostTask(FROM_HERE,
68 base::Bind(&BackgroundShellServiceLoader::LoadServiceOnBackgroundThread,
69 base::Unretained(this), manager, url,
70 base::Owned(
71 new ScopedMessagePipeHandle(shell_handle.Pass()))));
74 void BackgroundShellServiceLoader::OnServiceError(
75 ServiceManager* manager, const GURL& url) {
76 task_runner_->PostTask(FROM_HERE,
77 base::Bind(
78 &BackgroundShellServiceLoader::OnServiceErrorOnBackgroundThread,
79 base::Unretained(this), manager, url));
82 void BackgroundShellServiceLoader::Run() {
83 base::MessageLoop message_loop(message_loop_type_);
84 base::RunLoop loop;
85 task_runner_ = message_loop.task_runner();
86 quit_closure_ = loop.QuitClosure();
87 message_loop_created_.Signal();
88 loop.Run();
90 delete background_loader_;
91 background_loader_ = NULL;
92 // Destroy |loader_| on the thread it's actually used on.
93 loader_.reset();
96 void BackgroundShellServiceLoader::LoadServiceOnBackgroundThread(
97 ServiceManager* manager,
98 const GURL& url,
99 ScopedMessagePipeHandle* shell_handle) {
100 DCHECK(task_runner_->RunsTasksOnCurrentThread());
101 if (!background_loader_)
102 background_loader_ = new BackgroundLoader(loader_.get());
103 background_loader_->LoadService(manager, url, shell_handle->Pass());
106 void BackgroundShellServiceLoader::OnServiceErrorOnBackgroundThread(
107 ServiceManager* manager, const GURL& url) {
108 DCHECK(task_runner_->RunsTasksOnCurrentThread());
109 if (!background_loader_)
110 background_loader_ = new BackgroundLoader(loader_.get());
111 background_loader_->OnServiceError(manager, url);
114 } // namespace mojo