diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-06 09:10:00 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-06 09:10:00 +0000 |
commit | 34c758ba3a40ac0e15c9260e529cb2b05b5b92cf (patch) | |
tree | bec504efb3710d670dac56c8c6b1c90df633055d /mojo/service_manager | |
parent | c9024fc64322c3a1edf08c8c8b3656082c192edd (diff) | |
download | chromium_src-34c758ba3a40ac0e15c9260e529cb2b05b5b92cf.zip chromium_src-34c758ba3a40ac0e15c9260e529cb2b05b5b92cf.tar.gz chromium_src-34c758ba3a40ac0e15c9260e529cb2b05b5b92cf.tar.bz2 |
Adds ability to load services on background thread
And enables this for the native viewport. Currently the native
viewport implementation can end up synchronously waiting for
messages. This means if the viewmanager (which uses the native
viewport) and native viewport end up on the same thread they can
easily deadlock. For now I'm moving native viewport to its own
thread. Long term native viewport should live in its own process
(according to piman).
BUG=365012
TEST=none
R=davemoore@chromium.org
Review URL: https://codereview.chromium.org/263163005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@268471 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo/service_manager')
-rw-r--r-- | mojo/service_manager/background_service_loader.cc | 94 | ||||
-rw-r--r-- | mojo/service_manager/background_service_loader.h | 57 | ||||
-rw-r--r-- | mojo/service_manager/service_loader.h | 2 | ||||
-rw-r--r-- | mojo/service_manager/service_manager.h | 1 |
4 files changed, 152 insertions, 2 deletions
diff --git a/mojo/service_manager/background_service_loader.cc b/mojo/service_manager/background_service_loader.cc new file mode 100644 index 0000000..ba365b0 --- /dev/null +++ b/mojo/service_manager/background_service_loader.cc @@ -0,0 +1,94 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// 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 "base/bind.h" +#include "mojo/service_manager/service_manager.h" + +namespace mojo { + +class BackgroundServiceLoader::BackgroundLoader { + public: + explicit BackgroundLoader(ServiceLoader* loader) : loader_(loader) {} + ~BackgroundLoader() {} + + void LoadService(ServiceManager* manager, + const GURL& url, + ScopedShellHandle shell_handle) { + loader_->LoadService(manager, url, shell_handle.Pass()); + } + + void OnServiceError(ServiceManager* manager, const GURL& url) { + loader_->OnServiceError(manager, url); + } + + private: + ServiceLoader* loader_; // Owned by BackgroundServiceLoader + + DISALLOW_COPY_AND_ASSIGN(BackgroundLoader); +}; + +BackgroundServiceLoader::BackgroundServiceLoader( + scoped_ptr<ServiceLoader> real_loader, + const char* thread_name) + : loader_(real_loader.Pass()), + thread_(thread_name), + background_loader_(NULL) { +} + +BackgroundServiceLoader::~BackgroundServiceLoader() { + if (thread_.IsRunning()) { + thread_.message_loop()->PostTask( + FROM_HERE, + base::Bind(&BackgroundServiceLoader::ShutdownOnBackgroundThread, + base::Unretained(this))); + } + thread_.Stop(); +} + +void BackgroundServiceLoader::LoadService(ServiceManager* manager, + const GURL& url, + ScopedShellHandle service_handle) { + if (!thread_.IsRunning()) + thread_.Start(); + thread_.message_loop()->PostTask( + FROM_HERE, + base::Bind(&BackgroundServiceLoader::LoadServiceOnBackgroundThread, + base::Unretained(this), manager, url, + base::Owned(new ScopedShellHandle(service_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 BackgroundServiceLoader::LoadServiceOnBackgroundThread( + ServiceManager* manager, + const GURL& url, + ScopedShellHandle* shell_handle) { + if (!background_loader_) + background_loader_ = new BackgroundLoader(loader_.get()); + background_loader_->LoadService(manager, url, shell_handle->Pass()); +} + +void BackgroundServiceLoader::OnServiceErrorOnBackgroundThread( + ServiceManager* manager, + const GURL& url) { + if (!background_loader_) + background_loader_ = new BackgroundLoader(loader_.get()); + background_loader_->OnServiceError(manager, url); +} + +void BackgroundServiceLoader::ShutdownOnBackgroundThread() { + delete background_loader_; +} + +} // namespace mojo diff --git a/mojo/service_manager/background_service_loader.h b/mojo/service_manager/background_service_loader.h new file mode 100644 index 0000000..b505941 --- /dev/null +++ b/mojo/service_manager/background_service_loader.h @@ -0,0 +1,57 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_SERVICE_MANAGER_BACKGROUND_SERVICE_LOADER_H_ +#define MOJO_SERVICE_MANAGER_BACKGROUND_SERVICE_LOADER_H_ + +#include "base/memory/scoped_ptr.h" +#include "base/threading/thread.h" +#include "mojo/service_manager/service_loader.h" + +namespace mojo { + +class ServiceManager; + +// ServiceLoader implementation that creates a background thread and issues load +// requests there. +class MOJO_SERVICE_MANAGER_EXPORT BackgroundServiceLoader + : public ServiceLoader { + public: + BackgroundServiceLoader(scoped_ptr<ServiceLoader> real_loader, + const char* thread_name); + virtual ~BackgroundServiceLoader(); + + // ServiceLoader overrides: + virtual void LoadService(ServiceManager* manager, + const GURL& url, + ScopedShellHandle service_handle) OVERRIDE; + virtual void OnServiceError(ServiceManager* manager, + const GURL& url) OVERRIDE; + + private: + class BackgroundLoader; + + // These functions are exected on the background thread. They call through + // to |background_loader_| to do the actual loading. + // TODO: having this code take a |manager| is fragile (as ServiceManager isn't + // thread safe). + void LoadServiceOnBackgroundThread(ServiceManager* manager, + const GURL& url, + ScopedShellHandle* shell_handle); + void OnServiceErrorOnBackgroundThread(ServiceManager* manager, + const GURL& url); + void ShutdownOnBackgroundThread(); + + scoped_ptr<ServiceLoader> loader_; + base::Thread thread_; + + // Lives on |thread_|. Trivial interface that calls through to |loader_|. + BackgroundLoader* background_loader_; + + DISALLOW_COPY_AND_ASSIGN(BackgroundServiceLoader); +}; + +} // namespace mojo + +#endif // MOJO_SERVICE_MANAGER_BACKGROUND_SERVICE_LOADER_H_ diff --git a/mojo/service_manager/service_loader.h b/mojo/service_manager/service_loader.h index 42b593e..7567ad3 100644 --- a/mojo/service_manager/service_loader.h +++ b/mojo/service_manager/service_loader.h @@ -17,7 +17,7 @@ class ServiceManager; // specific url. class MOJO_SERVICE_MANAGER_EXPORT ServiceLoader { public: - virtual ~ServiceLoader() {}; + virtual ~ServiceLoader() {} virtual void LoadService(ServiceManager* manager, const GURL& url, ScopedShellHandle service_handle) = 0; diff --git a/mojo/service_manager/service_manager.h b/mojo/service_manager/service_manager.h index ae41127..1e3fcbd 100644 --- a/mojo/service_manager/service_manager.h +++ b/mojo/service_manager/service_manager.h @@ -8,7 +8,6 @@ #include <map> #include "base/basictypes.h" -#include "base/callback.h" #include "base/gtest_prod_util.h" #include "base/memory/scoped_ptr.h" #include "mojo/public/interfaces/shell/shell.mojom.h" |