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