| 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 39%
|
| rename from mojo/service_manager/background_service_loader.cc
|
| rename to mojo/service_manager/background_shell_service_loader.cc
|
| index 8c60a2cc00696df313e989933dcf63d6875d480f..6d7a2582108628a29c9a728b9be3886ffe978b46 100644
|
| --- a/mojo/service_manager/background_service_loader.cc
|
| +++ b/mojo/service_manager/background_shell_service_loader.cc
|
| @@ -2,14 +2,15 @@
|
| // 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 "base/run_loop.h"
|
| #include "mojo/service_manager/service_manager.h"
|
|
|
| namespace mojo {
|
|
|
| -class BackgroundServiceLoader::BackgroundLoader {
|
| +class BackgroundShellServiceLoader::BackgroundLoader {
|
| public:
|
| explicit BackgroundLoader(ServiceLoader* loader) : loader_(loader) {}
|
| ~BackgroundLoader() {}
|
| @@ -25,81 +26,93 @@ 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),
|
| + loader_(real_loader.Pass()),
|
| message_loop_type_(message_loop_type),
|
| + thread_name_(thread_name),
|
| + message_loop_created_(true, false),
|
| background_loader_(NULL) {
|
| }
|
|
|
| -BackgroundServiceLoader::~BackgroundServiceLoader() {
|
| - if (thread_.IsRunning()) {
|
| - thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&BackgroundServiceLoader::ShutdownOnBackgroundThread,
|
| - base::Unretained(this)));
|
| +BackgroundShellServiceLoader::~BackgroundShellServiceLoader() {
|
| + if (thread_) {
|
| + if (quit_on_shutdown_)
|
| + task_runner_->PostTask(FROM_HERE, quit_closure_);
|
| + thread_->Join();
|
| }
|
| - thread_.Stop();
|
| }
|
|
|
| -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));
|
| + if (!thread_) {
|
| + // 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_.reset(new base::DelegateSimpleThread(this, thread_name_));
|
| + thread_->Start();
|
| + message_loop_created_.Wait();
|
| + DCHECK(task_runner_);
|
| }
|
| - thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&BackgroundServiceLoader::LoadServiceOnBackgroundThread,
|
| +
|
| + 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() {
|
| + base::MessageLoop message_loop(message_loop_type_);
|
| + base::RunLoop loop;
|
| + task_runner_ = message_loop.task_runner();
|
| + quit_closure_ = loop.QuitClosure();
|
| + message_loop_created_.Signal();
|
| + 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
|
|
|