Chromium Code Reviews| Index: mojo/service_manager/background_shell_service_loader.cc |
| diff --git a/mojo/service_manager/background_service_loader.cc b/mojo/service_manager/background_shell_service_loader.cc |
| similarity index 36% |
| rename from mojo/service_manager/background_service_loader.cc |
| rename to mojo/service_manager/background_shell_service_loader.cc |
| index 8c60a2cc00696df313e989933dcf63d6875d480f..a136a9510c90c99b65302944cef293ece4c0bbd6 100644 |
| --- a/mojo/service_manager/background_service_loader.cc |
| +++ b/mojo/service_manager/background_shell_service_loader.cc |
| @@ -2,14 +2,22 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| -#include "mojo/service_manager/background_service_loader.h" |
| +#include "mojo/service_manager/background_shell_service_loader.h" |
| #include "base/bind.h" |
| #include "mojo/service_manager/service_manager.h" |
| namespace mojo { |
| -class BackgroundServiceLoader::BackgroundLoader { |
| +namespace { |
| + |
| +void QuitLoop() { |
| + base::MessageLoop::current()->Quit(); |
|
sky
2014/07/31 20:59:33
Use a RunLoop.
tim (not reviewing)
2014/07/31 22:17:28
Done, assuming you meant Run() a RunLoop in Backgr
sky
2014/08/04 18:56:25
I was actually think you use the base::RunLoop you
tim (not reviewing)
2014/08/04 19:51:29
I see. It'd have to be heap allocated pointer in t
|
| +} |
| + |
| +} // namespace |
| + |
| +class BackgroundShellServiceLoader::BackgroundLoader { |
| public: |
| explicit BackgroundLoader(ServiceLoader* loader) : loader_(loader) {} |
| ~BackgroundLoader() {} |
| @@ -25,81 +33,100 @@ class BackgroundServiceLoader::BackgroundLoader { |
| } |
| private: |
| - base::MessageLoop::Type message_loop_type_; |
| - ServiceLoader* loader_; // Owned by BackgroundServiceLoader |
| + ServiceLoader* loader_; // Owned by BackgroundShellServiceLoader |
| DISALLOW_COPY_AND_ASSIGN(BackgroundLoader); |
| }; |
| -BackgroundServiceLoader::BackgroundServiceLoader( |
| +BackgroundShellServiceLoader::BackgroundShellServiceLoader( |
| scoped_ptr<ServiceLoader> real_loader, |
| - const char* thread_name, |
| + const std::string& thread_name, |
| base::MessageLoop::Type message_loop_type) |
| - : loader_(real_loader.Pass()), |
| - thread_(thread_name), |
| + : quit_on_shutdown_(false), |
| + loaded_service_(false), |
| + loader_(real_loader.Pass()), |
| message_loop_type_(message_loop_type), |
| + message_loop_created_(true, false), |
| + thread_(this, thread_name), |
| background_loader_(NULL) { |
| + // TODO(tim): It'd be nice if we could just have each LoadService call result |
| + // in a new thread like DynamicService{Loader, Runner}. But some loaders are |
| + // creating multiple ApplicationImpls (NetworkServiceLoader) sharing a |
| + // delegate (etc). So we have to keep it single threaded, wait for the |
| + // thread to initialize, and post to the TaskRunner for subsequent LoadService |
| + // calls for now. |
| + thread_.Start(); |
| + message_loop_created_.Wait(); |
|
sky
2014/07/31 20:59:33
Why do we need to block here? Or for that matter s
tim (not reviewing)
2014/07/31 22:17:28
DelegateSimpleThread requires that it is both Star
|
| + DCHECK(task_runner_); |
| } |
| -BackgroundServiceLoader::~BackgroundServiceLoader() { |
| - if (thread_.IsRunning()) { |
| - thread_.message_loop()->PostTask( |
| - FROM_HERE, |
| - base::Bind(&BackgroundServiceLoader::ShutdownOnBackgroundThread, |
| - base::Unretained(this))); |
| - } |
| - thread_.Stop(); |
| +BackgroundShellServiceLoader::~BackgroundShellServiceLoader() { |
| + if (quit_on_shutdown_ || !loaded_service_) |
| + task_runner_->PostTask(FROM_HERE, base::Bind(&QuitLoop)); |
| + thread_.Join(); |
| } |
| -void BackgroundServiceLoader::LoadService( |
| +void BackgroundShellServiceLoader::LoadService( |
| ServiceManager* manager, |
| const GURL& url, |
| ScopedMessagePipeHandle shell_handle) { |
| - const int kDefaultStackSize = 0; |
| - if (!thread_.IsRunning()) { |
| - thread_.StartWithOptions( |
| - base::Thread::Options(message_loop_type_, kDefaultStackSize)); |
| - } |
| - thread_.message_loop()->PostTask( |
| - FROM_HERE, |
| - base::Bind(&BackgroundServiceLoader::LoadServiceOnBackgroundThread, |
| + loaded_service_ = true; |
| + task_runner_->PostTask(FROM_HERE, |
| + base::Bind(&BackgroundShellServiceLoader::LoadServiceOnBackgroundThread, |
| base::Unretained(this), manager, url, |
| base::Owned( |
| new ScopedMessagePipeHandle(shell_handle.Pass())))); |
| } |
| -void BackgroundServiceLoader::OnServiceError(ServiceManager* manager, |
| - const GURL& url) { |
| - if (!thread_.IsRunning()) |
| - thread_.Start(); |
| - thread_.message_loop()->PostTask( |
| - FROM_HERE, |
| - base::Bind(&BackgroundServiceLoader::OnServiceErrorOnBackgroundThread, |
| - base::Unretained(this), manager, url)); |
| +void BackgroundShellServiceLoader::OnServiceError( |
| + ServiceManager* manager, const GURL& url) { |
| + task_runner_->PostTask(FROM_HERE, |
| + base::Bind( |
| + &BackgroundShellServiceLoader::OnServiceErrorOnBackgroundThread, |
| + base::Unretained(this), manager, url)); |
| } |
| -void BackgroundServiceLoader::LoadServiceOnBackgroundThread( |
| - ServiceManager* manager, |
| - const GURL& url, |
| - ScopedMessagePipeHandle* shell_handle) { |
| +void BackgroundShellServiceLoader::Run() { |
| + scoped_ptr<base::MessageLoop> message_loop; |
|
sky
2014/07/31 20:59:33
You should be able to use MessageLoop(type) here.
tim (not reviewing)
2014/07/31 22:17:28
Ah.. forgot about that. Thanks!
|
| + switch (message_loop_type_) { |
| + case base::MessageLoop::TYPE_UI: |
| + message_loop.reset(new base::MessageLoopForUI()); |
| + break; |
| + case base::MessageLoop::TYPE_IO: |
| + message_loop.reset(new base::MessageLoopForIO()); |
| + break; |
| + case base::MessageLoop::TYPE_DEFAULT: |
| + message_loop.reset(new base::MessageLoop()); |
| + break; |
| + default: |
| + NOTREACHED(); |
| + } |
| + task_runner_ = message_loop->task_runner(); |
| + message_loop_created_.Signal(); |
| + message_loop->Run(); |
| + |
| + delete background_loader_; |
| + background_loader_ = NULL; |
| + // Destroy |loader_| on the thread it's actually used on. |
| + loader_.reset(); |
| +} |
| + |
| +void BackgroundShellServiceLoader::LoadServiceOnBackgroundThread( |
| + ServiceManager* manager, |
| + const GURL& url, |
| + ScopedMessagePipeHandle* shell_handle) { |
| + DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
| if (!background_loader_) |
| background_loader_ = new BackgroundLoader(loader_.get()); |
| - background_loader_->LoadService( |
| - manager, url, shell_handle->Pass()); |
| + background_loader_->LoadService(manager, url, shell_handle->Pass()); |
| } |
| -void BackgroundServiceLoader::OnServiceErrorOnBackgroundThread( |
| - ServiceManager* manager, |
| - const GURL& url) { |
| +void BackgroundShellServiceLoader::OnServiceErrorOnBackgroundThread( |
| + ServiceManager* manager, const GURL& url) { |
| + DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
| if (!background_loader_) |
| background_loader_ = new BackgroundLoader(loader_.get()); |
| background_loader_->OnServiceError(manager, url); |
| } |
| -void BackgroundServiceLoader::ShutdownOnBackgroundThread() { |
| - delete background_loader_; |
| - // Destroy |loader_| on the thread it's actually used on. |
| - loader_.reset(); |
| -} |
| - |
| } // namespace mojo |