diff options
author | scottmg@chromium.org <scottmg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-16 07:45:36 +0000 |
---|---|---|
committer | scottmg@chromium.org <scottmg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-16 07:45:36 +0000 |
commit | d7a2d89aee556017139f6bea76e328423e60277d (patch) | |
tree | 018c1358276c3c551e888568f1a0e19ab840da25 | |
parent | ed522c341e491b8aad34f3ac2d9c06669971627e (diff) | |
download | chromium_src-d7a2d89aee556017139f6bea76e328423e60277d.zip chromium_src-d7a2d89aee556017139f6bea76e328423e60277d.tar.gz chromium_src-d7a2d89aee556017139f6bea76e328423e60277d.tar.bz2 |
Set up content in-process main threads via factory
This code was previously #ifdef'd out based on CHROME_MULTIPLE_DLL. This works
for chrome, but not for test targets which link content_browser. content_browser
needs to not link against child-only targets (as they'll cause linking blink
into the browser dll).
Instead of having utility_process_host_impl, et al. own the in-process
implementation, use a factory to create them that's installed in test code, and
in chrome for supporting --single-process.
At the same time, remove the global CHROME_MULTIPLE_DLL define and localize it
to chrome_exe.gypi because it's too easy to use incorrectly.
TBR=darin
R=piman@chromium.org,jam@chromium.org
BUG=237249
Review URL: https://chromiumcodereview.appspot.com/23235002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@217968 0039d316-1c4b-4281-b951-d872f2087c98
25 files changed, 349 insertions, 190 deletions
diff --git a/build/common.gypi b/build/common.gypi index e95efab..df25eb4 100644 --- a/build/common.gypi +++ b/build/common.gypi @@ -1899,9 +1899,6 @@ '<(DEPTH)/base/allocator/allocator.gyp:type_profiler', ], }], - ['chrome_multiple_dll', { - 'defines': ['CHROME_MULTIPLE_DLL'], - }], ['OS=="linux" and clang==1 and host_arch=="ia32"', { # TODO(dmikurube): Remove -Wno-sentinel when Clang/LLVM is fixed. # See http://crbug.com/162818. diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc index 452818a..671f5af 100644 --- a/chrome/app/chrome_main_delegate.cc +++ b/chrome/app/chrome_main_delegate.cc @@ -744,8 +744,7 @@ int ChromeMainDelegate::RunProcess( const content::MainFunctionParams& main_function_params) { // ANDROID doesn't support "service", so no ServiceProcessMain, and arraysize // doesn't support empty array. So we comment out the block for Android. -#if !defined(OS_ANDROID) && \ - (!defined(CHROME_MULTIPLE_DLL) || defined(CHROME_MULTIPLE_DLL_BROWSER)) +#if !defined(OS_ANDROID) && !defined(CHROME_MULTIPLE_DLL_CHILD) static const MainFunction kMainFunctions[] = { #if defined(ENABLE_FULL_PRINTING) { switches::kServiceProcess, ServiceProcessMain }, @@ -756,9 +755,8 @@ int ChromeMainDelegate::RunProcess( mac_relauncher::internal::RelauncherMain }, #endif -#if !defined(DISABLE_NACL) && \ - (!defined(CHROME_MULTIPLE_DLL) || defined(CHROME_MULTIPLE_DLL_CHILD)) - { switches::kNaClLoaderProcess, NaClMain }, +#if !defined(DISABLE_NACL) && !defined(CHROME_MULTIPLE_DLL_BROWSER) + { switches::kNaClLoaderProcess, NaClMain }, #endif // DISABLE_NACL }; diff --git a/chrome/chrome_exe.gypi b/chrome/chrome_exe.gypi index 78047eb..67b0efa 100644 --- a/chrome/chrome_exe.gypi +++ b/chrome/chrome_exe.gypi @@ -436,6 +436,9 @@ '../third_party/widevine/cdm/widevine_cdm.gyp:widevinecdmadapter', ], }], + ['chrome_multiple_dll', { + 'defines': ['CHROME_MULTIPLE_DLL'], + }], ['OS=="mac" and asan==1', { 'xcode_settings': { # Override the outer definition of CHROMIUM_STRIP_SAVE_FILE. diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc index 6554d57..c7421ef 100644 --- a/content/app/content_main_runner.cc +++ b/content/app/content_main_runner.cc @@ -26,17 +26,23 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "content/browser/browser_main.h" +#include "content/browser/gpu/gpu_process_host.h" #include "content/common/set_process_title.h" #include "content/common/url_schemes.h" +#include "content/gpu/gpu_main_thread.h" #include "content/public/app/content_main_delegate.h" #include "content/public/app/startup_helper_win.h" #include "content/public/browser/content_browser_client.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/utility_process_host.h" #include "content/public/common/content_client.h" #include "content/public/common/content_constants.h" #include "content/public/common/content_paths.h" #include "content/public/common/content_switches.h" #include "content/public/common/main_function_params.h" #include "content/public/common/sandbox_init.h" +#include "content/renderer/renderer_main_thread.h" +#include "content/utility/utility_main_thread.h" #include "crypto/nss_util.h" #include "ipc/ipc_switches.h" #include "media/base/media.h" @@ -424,6 +430,13 @@ int RunNamedProcessTypeMain( #endif // !CHROME_MULTIPLE_DLL_BROWSER }; +#if !defined(CHROME_MULTIPLE_DLL_BROWSER) + UtilityProcessHost::RegisterUtilityMainThreadFactory(CreateUtilityMainThread); + RenderProcessHost::RegisterRendererMainThreadFactory( + CreateRendererMainThread); + GpuProcessHost::RegisterGpuMainThreadFactory(CreateGpuMainThread); +#endif + for (size_t i = 0; i < arraysize(kMainFunctions); ++i) { if (process_type == kMainFunctions[i].name) { if (delegate) { diff --git a/content/browser/DEPS b/content/browser/DEPS index 39be989..3a85518 100644 --- a/content/browser/DEPS +++ b/content/browser/DEPS @@ -10,10 +10,6 @@ include_rules = [ "+ui/webui", "+win8/util", - # For single-process mode. - "+content/child/child_process.h", - "+content/utility/utility_thread_impl.h", - # TODO(joi): This was misplaced; need to move it somewhere else, # since //content shouldn't depend on //components, which is a layer # above. diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 8cbb7aa..7839ea7 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc @@ -278,43 +278,6 @@ class GpuSandboxedProcessLauncherDelegate } // anonymous namespace -// Single process not supported in multiple dll mode currently. -#if !defined(CHROME_MULTIPLE_DLL) -// This class creates a GPU thread (instead of a GPU process), when running -// with --in-process-gpu or --single-process. -class GpuMainThread : public base::Thread { - public: - explicit GpuMainThread(const std::string& channel_id) - : base::Thread("Chrome_InProcGpuThread"), - channel_id_(channel_id), - gpu_process_(NULL) { - } - - virtual ~GpuMainThread() { - Stop(); - } - - protected: - virtual void Init() OVERRIDE { - gpu_process_ = new GpuProcess(); - // The process object takes ownership of the thread object, so do not - // save and delete the pointer. - gpu_process_->set_main_thread(new GpuChildThread(channel_id_)); - } - - virtual void CleanUp() OVERRIDE { - delete gpu_process_; - } - - private: - std::string channel_id_; - // Deleted in CleanUp() on the gpu thread, so don't use smart pointers. - GpuProcess* gpu_process_; - - DISALLOW_COPY_AND_ASSIGN(GpuMainThread); -}; -#endif // !CHROME_MULTIPLE_DLL - // static bool GpuProcessHost::ValidateHost(GpuProcessHost* host) { if (!host) @@ -401,6 +364,13 @@ void GpuProcessHost::SendOnIO(GpuProcessKind kind, } } +GpuMainThreadFactoryFunction g_gpu_main_thread_factory = NULL; + +void GpuProcessHost::RegisterGpuMainThreadFactory( + GpuMainThreadFactoryFunction create) { + g_gpu_main_thread_factory = create; +} + // static GpuProcessHost* GpuProcessHost::FromID(int host_id) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); @@ -598,19 +568,15 @@ bool GpuProcessHost::Init() { if (channel_id.empty()) return false; - // Single process not supported in multiple dll mode currently. -#if !defined(CHROME_MULTIPLE_DLL) - if (in_process_) { + if (in_process_ && g_gpu_main_thread_factory) { CommandLine::ForCurrentProcess()->AppendSwitch( switches::kDisableGpuWatchdog); - in_process_gpu_thread_.reset(new GpuMainThread(channel_id)); + in_process_gpu_thread_.reset(g_gpu_main_thread_factory(channel_id)); in_process_gpu_thread_->Start(); OnProcessLaunched(); // Fake a callback that the process is ready. - } else -#endif // !CHROME_MULTIPLE_DLL - if (!LaunchGpuProcess(channel_id)) { + } else if (!LaunchGpuProcess(channel_id)) { return false; } diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h index 8908a10..32345b7 100644 --- a/content/browser/gpu/gpu_process_host.h +++ b/content/browser/gpu/gpu_process_host.h @@ -44,6 +44,8 @@ class GpuMainThread; class RenderWidgetHostViewFrameSubscriber; class ShaderDiskCache; +typedef base::Thread* (*GpuMainThreadFactoryFunction)(const std::string& id); + class GpuProcessHost : public BrowserChildProcessHostDelegate, public IPC::Sender, public base::NonThreadSafe { @@ -82,6 +84,9 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate, CauseForGpuLaunch cause, IPC::Message* message); + CONTENT_EXPORT static void RegisterGpuMainThreadFactory( + GpuMainThreadFactoryFunction create); + // Get the GPU process host for the GPU process with the given ID. Returns // null if the process no longer exists. static GpuProcessHost* FromID(int host_id); @@ -214,9 +219,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate, bool swiftshader_rendering_; GpuProcessKind kind_; -#if !defined(CHROME_MULTIPLE_DLL) - scoped_ptr<GpuMainThread> in_process_gpu_thread_; -#endif + scoped_ptr<base::Thread> in_process_gpu_thread_; // Whether we actually launched a GPU process. bool process_launched_; diff --git a/content/browser/renderer_host/DEPS b/content/browser/renderer_host/DEPS index 34decdb..0848d36 100644 --- a/content/browser/renderer_host/DEPS +++ b/content/browser/renderer_host/DEPS @@ -5,10 +5,6 @@ include_rules = [ "+third_party/zlib", "+third_party/libyuv", - # For single-process mode. - "+content/renderer/render_process_impl.h", - "+content/renderer/render_thread_impl.h", - # The renderer_host files should only call upwards in the layering via the # delegate interfaces. "-content/browser/web_contents", diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 3b22bc8..25e5a05 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -118,8 +118,6 @@ #include "content/public/common/process_type.h" #include "content/public/common/result_codes.h" #include "content/public/common/url_constants.h" -#include "content/renderer/render_process_impl.h" -#include "content/renderer/render_thread_impl.h" #include "gpu/command_buffer/service/gpu_switches.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_logging.h" @@ -157,8 +155,6 @@ static const char* kSiteProcessMapKeyName = "content_site_process_map"; namespace content { namespace { -base::MessageLoop* g_in_process_thread; - void CacheShaderInfo(int32 id, base::FilePath path) { ShaderCacheFactory::GetInstance()->SetCacheInfo(id, path); } @@ -167,57 +163,6 @@ void RemoveShaderInfo(int32 id) { ShaderCacheFactory::GetInstance()->RemoveCacheInfo(id); } -} // namespace - -#if !defined(CHROME_MULTIPLE_DLL) - -// This class creates the IO thread for the renderer when running in -// single-process mode. It's not used in multi-process mode. -class RendererMainThread : public base::Thread { - public: - explicit RendererMainThread(const std::string& channel_id) - : Thread("Chrome_InProcRendererThread"), - channel_id_(channel_id) { - } - - virtual ~RendererMainThread() { - Stop(); - } - - protected: - virtual void Init() OVERRIDE { - render_process_.reset(new RenderProcessImpl()); - new RenderThreadImpl(channel_id_); - g_in_process_thread = message_loop(); - } - - virtual void CleanUp() OVERRIDE { - g_in_process_thread = NULL; - render_process_.reset(); - - // It's a little lame to manually set this flag. But the single process - // RendererThread will receive the WM_QUIT. We don't need to assert on - // this thread, so just force the flag manually. - // If we want to avoid this, we could create the InProcRendererThread - // directly with _beginthreadex() rather than using the Thread class. - // We used to set this flag in the Init function above. However there - // other threads like WebThread which are created by this thread - // which resets this flag. Please see Thread::StartWithOptions. Setting - // this flag to true in Cleanup works around these problems. - SetThreadWasQuitProperly(true); - } - - private: - std::string channel_id_; - scoped_ptr<RenderProcess> render_process_; - - DISALLOW_COPY_AND_ASSIGN(RendererMainThread); -}; - -#endif - -namespace { - // Helper class that we pass to ResourceMessageFilter so that it can find the // right net::URLRequestContext for a request. class RendererURLRequestContextSelector @@ -339,6 +284,20 @@ class RendererSandboxedProcessLauncherDelegate } // namespace +RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL; + +void RenderProcessHost::RegisterRendererMainThreadFactory( + RendererMainThreadFactoryFunction create) { + g_renderer_main_thread_factory = create; +} + +base::MessageLoop* g_in_process_thread; + +base::MessageLoop* + RenderProcessHostImpl::GetInProcessRendererThreadForTesting() { + return g_in_process_thread; +} + // Stores the maximum number of renderer processes the content module can // create. static size_t g_max_renderer_count_override = 0; @@ -511,15 +470,14 @@ bool RenderProcessHostImpl::Init() { CreateMessageFilters(); // Single-process mode not supported in multiple-dll mode currently. -#if !defined(CHROME_MULTIPLE_DLL) - if (run_renderer_in_process()) { + if (run_renderer_in_process() && g_renderer_main_thread_factory) { // Crank up a thread and run the initialization there. With the way that // messages flow between the browser and renderer, this thread is required // to prevent a deadlock in single-process mode. Since the primordial // thread in the renderer process runs the WebKit code and can sometimes // make blocking calls to the UI thread (i.e. this thread), they need to run // on separate threads. - in_process_renderer_.reset(new RendererMainThread(channel_id)); + in_process_renderer_.reset(g_renderer_main_thread_factory(channel_id)); base::Thread::Options options; #if defined(OS_WIN) && !defined(OS_MACOSX) @@ -532,10 +490,10 @@ bool RenderProcessHostImpl::Init() { #endif in_process_renderer_->StartWithOptions(options); + g_in_process_thread = in_process_renderer_->message_loop(); + OnProcessLaunched(); // Fake a callback that the process is ready. - } else -#endif // !CHROME_MULTIPLE_DLL - { + } else { // Build command line for renderer. We call AppendRendererCommandLine() // first so the process type argument will appear first. CommandLine* cmd_line = new CommandLine(renderer_path); @@ -1617,11 +1575,6 @@ void RenderProcessHostImpl::RegisterProcessHostForSite( map->RegisterProcess(site, process); } -base::MessageLoop* - RenderProcessHostImpl::GetInProcessRendererThreadForTesting() { - return g_in_process_thread; -} - void RenderProcessHostImpl::ProcessDied(bool already_dead) { // Our child process has died. If we didn't expect it, it's a crash. // In any case, we need to let everyone know it's gone. diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index 72ec846..9d195f5 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h @@ -264,10 +264,8 @@ class CONTENT_EXPORT RenderProcessHostImpl // This is used to clear our cache five seconds after the last use. base::DelayTimer<RenderProcessHostImpl> cached_dibs_cleaner_; -#if !defined(CHROME_MULTIPLE_DLL) // Used in single-process mode. - scoped_ptr<RendererMainThread> in_process_renderer_; -#endif + scoped_ptr<base::Thread> in_process_renderer_; // True after Init() has been called. We can't just check channel_ because we // also reset that in the case of process termination. diff --git a/content/browser/utility_process_host_impl.cc b/content/browser/utility_process_host_impl.cc index 2e56218..766b82e 100644 --- a/content/browser/utility_process_host_impl.cc +++ b/content/browser/utility_process_host_impl.cc @@ -16,7 +16,6 @@ #include "base/synchronization/waitable_event.h" #include "content/browser/browser_child_process_host_impl.h" #include "content/browser/renderer_host/render_process_host_impl.h" -#include "content/child/child_process.h" #include "content/common/child_process_host_impl.h" #include "content/common/utility_messages.h" #include "content/public/browser/browser_thread.h" @@ -24,7 +23,6 @@ #include "content/public/browser/utility_process_host_client.h" #include "content/public/common/content_switches.h" #include "content/public/common/process_type.h" -#include "content/utility/utility_thread_impl.h" #include "ipc/ipc_switches.h" #include "ui/base/ui_base_switches.h" @@ -53,53 +51,8 @@ private: }; #endif -// We want to ensure there's only one utility thread running at a time, as there -// are many globals used in the utility process. -static base::LazyInstance<base::Lock> g_one_utility_thread_lock; -// Single process not supported in multiple dll mode currently. -#if !defined(CHROME_MULTIPLE_DLL) -class UtilityMainThread : public base::Thread { - public: - UtilityMainThread(const std::string& channel_id) - : Thread("Chrome_InProcUtilityThread"), - channel_id_(channel_id) { - } - - virtual ~UtilityMainThread() { - Stop(); - } - - private: - // base::Thread implementation: - virtual void Init() OVERRIDE { - // We need to return right away or else the main thread that started us will - // hang. - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&UtilityMainThread::InitInternal, base::Unretained(this))); - } - - virtual void CleanUp() OVERRIDE { - child_process_.reset(); - - // See comment in RendererMainThread. - SetThreadWasQuitProperly(true); - g_one_utility_thread_lock.Get().Release(); - } - - void InitInternal() { - g_one_utility_thread_lock.Get().Acquire(); - child_process_.reset(new ChildProcess()); - child_process_->set_main_thread(new UtilityThreadImpl(channel_id_)); - } - - std::string channel_id_; - scoped_ptr<ChildProcess> child_process_; - - DISALLOW_COPY_AND_ASSIGN(UtilityMainThread); -}; -#endif // !CHROME_MULTIPLE_DLL +UtilityMainThreadFactoryFunction g_utility_main_thread_factory = NULL; UtilityProcessHost* UtilityProcessHost::Create( UtilityProcessHostClient* client, @@ -107,6 +60,11 @@ UtilityProcessHost* UtilityProcessHost::Create( return new UtilityProcessHostImpl(client, client_task_runner); } +void UtilityProcessHost::RegisterUtilityMainThreadFactory( + UtilityMainThreadFactoryFunction create) { + g_utility_main_thread_factory = create; +} + UtilityProcessHostImpl::UtilityProcessHostImpl( UtilityProcessHostClient* client, base::SequencedTaskRunner* client_task_runner) @@ -196,15 +154,13 @@ bool UtilityProcessHostImpl::StartProcess() { return false; // Single process not supported in multiple dll mode currently. -#if !defined(CHROME_MULTIPLE_DLL) - if (RenderProcessHost::run_renderer_in_process()) { + if (RenderProcessHost::run_renderer_in_process() && + g_utility_main_thread_factory) { // See comment in RenderProcessHostImpl::Init() for the background on why we // support single process mode this way. - in_process_thread_.reset(new UtilityMainThread(channel_id)); + in_process_thread_.reset(g_utility_main_thread_factory(channel_id)); in_process_thread_->Start(); - } else -#endif // !CHROME_MULTIPLE_DLL - { + } else { const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); int child_flags = child_flags_; diff --git a/content/browser/utility_process_host_impl.h b/content/browser/utility_process_host_impl.h index 6eecd3d..5443e09 100644 --- a/content/browser/utility_process_host_impl.h +++ b/content/browser/utility_process_host_impl.h @@ -18,11 +18,11 @@ namespace base { class SequencedTaskRunner; +class Thread; } namespace content { class BrowserChildProcessHostImpl; -class UtilityMainThread; class CONTENT_EXPORT UtilityProcessHostImpl : public NON_EXPORTED_BASE(UtilityProcessHost), @@ -83,10 +83,8 @@ class CONTENT_EXPORT UtilityProcessHostImpl scoped_ptr<BrowserChildProcessHostImpl> process_; -#if !defined(CHROME_MULTIPLE_DLL) // Used in single-process mode instead of process_. - scoped_ptr<UtilityMainThread> in_process_thread_; -#endif + scoped_ptr<base::Thread> in_process_thread_; DISALLOW_COPY_AND_ASSIGN(UtilityProcessHostImpl); }; diff --git a/content/content_gpu.gypi b/content/content_gpu.gypi index e1a28ba..5dba0ac 100644 --- a/content/content_gpu.gypi +++ b/content/content_gpu.gypi @@ -14,6 +14,8 @@ 'gpu/gpu_process.h', 'gpu/gpu_child_thread.cc', 'gpu/gpu_child_thread.h', + 'gpu/gpu_main_thread.cc', + 'gpu/gpu_main_thread.h', 'gpu/gpu_watchdog_thread.cc', 'gpu/gpu_watchdog_thread.h', ], diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 5c63588..119f0d3 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -466,6 +466,8 @@ 'renderer/renderer_main_platform_delegate_linux.cc', 'renderer/renderer_main_platform_delegate_mac.mm', 'renderer/renderer_main_platform_delegate_win.cc', + 'renderer/renderer_main_thread.cc', + 'renderer/renderer_main_thread.h', 'renderer/renderer_webapplicationcachehost_impl.cc', 'renderer/renderer_webapplicationcachehost_impl.h', 'renderer/renderer_webcookiejar_impl.cc', diff --git a/content/content_tests.gypi b/content/content_tests.gypi index d26cdd2..0574891 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi @@ -168,6 +168,7 @@ }, { # OS != "ios" 'dependencies': [ 'content_child', + 'content_gpu', 'content_ppapi_plugin', 'content_renderer', 'content_utility', diff --git a/content/content_utility.gypi b/content/content_utility.gypi index 96aef6c..a152c95 100644 --- a/content/content_utility.gypi +++ b/content/content_utility.gypi @@ -12,6 +12,8 @@ 'public/utility/utility_thread.cc', 'public/utility/utility_thread.h', 'utility/utility_main.cc', + 'utility/utility_main_thread.cc', + 'utility/utility_main_thread.h', 'utility/utility_thread_impl.cc', 'utility/utility_thread_impl.h', ], diff --git a/content/gpu/gpu_main_thread.cc b/content/gpu/gpu_main_thread.cc new file mode 100644 index 0000000..65fef13 --- /dev/null +++ b/content/gpu/gpu_main_thread.cc @@ -0,0 +1,37 @@ +// Copyright 2013 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 "content/gpu/gpu_main_thread.h" + +#include "content/gpu/gpu_child_thread.h" +#include "content/gpu/gpu_process.h" + +namespace content { + +GpuMainThread::GpuMainThread(const std::string& channel_id) + : base::Thread("Chrome_InProcGpuThread"), + channel_id_(channel_id), + gpu_process_(NULL) { +} + +GpuMainThread::~GpuMainThread() { + Stop(); +} + +void GpuMainThread::Init() { + gpu_process_ = new GpuProcess(); + // The process object takes ownership of the thread object, so do not + // save and delete the pointer. + gpu_process_->set_main_thread(new GpuChildThread(channel_id_)); +} + +void GpuMainThread::CleanUp() { + delete gpu_process_; +} + +base::Thread* CreateGpuMainThread(const std::string& channel_id) { + return new GpuMainThread(channel_id); +} + +} // namespace content diff --git a/content/gpu/gpu_main_thread.h b/content/gpu/gpu_main_thread.h new file mode 100644 index 0000000..f34f431 --- /dev/null +++ b/content/gpu/gpu_main_thread.h @@ -0,0 +1,38 @@ +// Copyright 2013 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 CONTENT_GPU_GPU_MAIN_THREAD_H_ +#define CONTENT_GPU_GPU_MAIN_THREAD_H_ + +#include "base/threading/thread.h" +#include "content/common/content_export.h" + +namespace content { + +class GpuProcess; + +// This class creates a GPU thread (instead of a GPU process), when running +// with --in-process-gpu or --single-process. +class GpuMainThread : public base::Thread { + public: + explicit GpuMainThread(const std::string& channel_id); + virtual ~GpuMainThread(); + + protected: + virtual void Init() OVERRIDE; + virtual void CleanUp() OVERRIDE; + + private: + std::string channel_id_; + // Deleted in CleanUp() on the gpu thread, so don't use smart pointers. + GpuProcess* gpu_process_; + + DISALLOW_COPY_AND_ASSIGN(GpuMainThread); +}; + +CONTENT_EXPORT base::Thread* CreateGpuMainThread(const std::string& channel_id); + +} // namespace content + +#endif // CONTENT_GPU_GPU_MAIN_THREAD_H_ diff --git a/content/public/browser/render_process_host.h b/content/public/browser/render_process_host.h index ccc1e72..35627c7 100644 --- a/content/public/browser/render_process_host.h +++ b/content/public/browser/render_process_host.h @@ -30,6 +30,9 @@ class TimeDelta; namespace content { +typedef base::Thread* (*RendererMainThreadFactoryFunction)( + const std::string& id); + // Interface that represents the browser side of the browser <-> renderer // communication channel. There will generally be one RenderProcessHost per // renderer process. @@ -248,6 +251,9 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Sender, // Returns the current max number of renderer processes used by the content // module. static size_t GetMaxRendererProcessCount(); + + static void RegisterRendererMainThreadFactory( + RendererMainThreadFactoryFunction create); }; } // namespace content. diff --git a/content/public/browser/utility_process_host.h b/content/public/browser/utility_process_host.h index 4c7e192..d85df1e 100644 --- a/content/public/browser/utility_process_host.h +++ b/content/public/browser/utility_process_host.h @@ -6,6 +6,7 @@ #define CONTENT_PUBLIC_BROWSER_UTILITY_PROCESS_HOST_H_ #include "base/process/launch.h" +#include "base/threading/thread.h" #include "content/common/content_export.h" #include "ipc/ipc_sender.h" @@ -18,6 +19,9 @@ namespace content { class UtilityProcessHostClient; struct ChildProcessData; +typedef base::Thread* (*UtilityMainThreadFactoryFunction)( + const std::string& id); + // This class acts as the browser-side host to a utility child process. A // utility process is a short-lived process that is created to run a specific // task. This class lives solely on the IO thread. @@ -66,6 +70,9 @@ class UtilityProcessHost : public IPC::Sender, #if defined(OS_POSIX) virtual void SetEnv(const base::EnvironmentVector& env) = 0; #endif + + CONTENT_EXPORT static void RegisterUtilityMainThreadFactory( + UtilityMainThreadFactoryFunction create); }; }; // namespace content diff --git a/content/public/test/content_test_suite_base.cc b/content/public/test/content_test_suite_base.cc index 5bf5b5e..f245683 100644 --- a/content/public/test/content_test_suite_base.cc +++ b/content/public/test/content_test_suite_base.cc @@ -10,9 +10,15 @@ #include "base/test/test_suite.h" #include "base/threading/sequenced_worker_pool.h" #include "content/browser/browser_thread_impl.h" +#include "content/browser/gpu/gpu_process_host.h" #include "content/common/url_schemes.h" +#include "content/gpu/gpu_main_thread.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/utility_process_host.h" #include "content/public/common/content_client.h" #include "content/public/common/content_paths.h" +#include "content/renderer/renderer_main_thread.h" +#include "content/utility/utility_main_thread.h" #include "media/base/media.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ui_base_paths.h" @@ -60,6 +66,13 @@ void ContentTestSuiteBase::Initialize() { ui::shell_dialogs::RegisterJni(env); #endif +#if !defined(OS_IOS) + UtilityProcessHost::RegisterUtilityMainThreadFactory(CreateUtilityMainThread); + RenderProcessHost::RegisterRendererMainThreadFactory( + CreateRendererMainThread); + GpuProcessHost::RegisterGpuMainThreadFactory(CreateGpuMainThread); +#endif + if (external_libraries_enabled_) media::InitializeMediaLibraryForTesting(); diff --git a/content/renderer/renderer_main_thread.cc b/content/renderer/renderer_main_thread.cc new file mode 100644 index 0000000..c6704c83 --- /dev/null +++ b/content/renderer/renderer_main_thread.cc @@ -0,0 +1,45 @@ +// Copyright 2013 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 "content/renderer/renderer_main_thread.h" + +#include "content/renderer/render_process.h" +#include "content/renderer/render_process_impl.h" +#include "content/renderer/render_thread_impl.h" + +namespace content { + +RendererMainThread::RendererMainThread(const std::string& channel_id) + : Thread("Chrome_InProcRendererThread"), channel_id_(channel_id) { +} + +RendererMainThread::~RendererMainThread() { + Stop(); +} + +void RendererMainThread::Init() { + render_process_.reset(new RenderProcessImpl()); + new RenderThreadImpl(channel_id_); +} + +void RendererMainThread::CleanUp() { + render_process_.reset(); + + // It's a little lame to manually set this flag. But the single process + // RendererThread will receive the WM_QUIT. We don't need to assert on + // this thread, so just force the flag manually. + // If we want to avoid this, we could create the InProcRendererThread + // directly with _beginthreadex() rather than using the Thread class. + // We used to set this flag in the Init function above. However there + // other threads like WebThread which are created by this thread + // which resets this flag. Please see Thread::StartWithOptions. Setting + // this flag to true in Cleanup works around these problems. + SetThreadWasQuitProperly(true); +} + +base::Thread* CreateRendererMainThread(const std::string& channel_id) { + return new RendererMainThread(channel_id); +} + +} // namespace content diff --git a/content/renderer/renderer_main_thread.h b/content/renderer/renderer_main_thread.h new file mode 100644 index 0000000..dca7cb8 --- /dev/null +++ b/content/renderer/renderer_main_thread.h @@ -0,0 +1,39 @@ +// Copyright 2013 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 CONTENT_RENDERER_RENDERER_MAIN_THREAD_H_ +#define CONTENT_RENDERER_RENDERER_MAIN_THREAD_H_ + +#include <string> + +#include "base/threading/thread.h" +#include "content/common/content_export.h" + +namespace content { +class RenderProcess; + +// This class creates the IO thread for the renderer when running in +// single-process mode. It's not used in multi-process mode. +class RendererMainThread : public base::Thread { + public: + explicit RendererMainThread(const std::string& channel_id); + virtual ~RendererMainThread(); + + protected: + virtual void Init() OVERRIDE; + virtual void CleanUp() OVERRIDE; + + private: + std::string channel_id_; + scoped_ptr<RenderProcess> render_process_; + + DISALLOW_COPY_AND_ASSIGN(RendererMainThread); +}; + +CONTENT_EXPORT base::Thread* CreateRendererMainThread( + const std::string& channel_id); + +} // namespace content + +#endif // CONTENT_RENDERER_RENDERER_MAIN_THREAD_H_ diff --git a/content/utility/utility_main_thread.cc b/content/utility/utility_main_thread.cc new file mode 100644 index 0000000..7d97399 --- /dev/null +++ b/content/utility/utility_main_thread.cc @@ -0,0 +1,50 @@ +// Copyright 2013 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 "content/utility/utility_main_thread.h" + +#include "content/child/child_process.h" +#include "content/utility/utility_thread_impl.h" + +namespace content { + +// We want to ensure there's only one utility thread running at a time, as there +// are many globals used in the utility process. +static base::LazyInstance<base::Lock> g_one_utility_thread_lock; + +UtilityMainThread::UtilityMainThread(const std::string& channel_id) + : Thread("Chrome_InProcUtilityThread"), channel_id_(channel_id) { +} + +UtilityMainThread::~UtilityMainThread() { + Stop(); +} + +void UtilityMainThread::Init() { + // We need to return right away or else the main thread that started us will + // hang. + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&UtilityMainThread::InitInternal, base::Unretained(this))); +} + +void UtilityMainThread::CleanUp() { + child_process_.reset(); + + // See comment in RendererMainThread. + SetThreadWasQuitProperly(true); + g_one_utility_thread_lock.Get().Release(); +} + +void UtilityMainThread::InitInternal() { + g_one_utility_thread_lock.Get().Acquire(); + child_process_.reset(new ChildProcess()); + child_process_->set_main_thread(new UtilityThreadImpl(channel_id_)); +} + +base::Thread* CreateUtilityMainThread(const std::string& channel_id) { + return new UtilityMainThread(channel_id); +} + +} // namespace content diff --git a/content/utility/utility_main_thread.h b/content/utility/utility_main_thread.h new file mode 100644 index 0000000..43e22b7 --- /dev/null +++ b/content/utility/utility_main_thread.h @@ -0,0 +1,40 @@ +// Copyright 2013 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 CONTENT_UTILITY_UTILITY_MAIN_THREAD_H_ +#define CONTENT_UTILITY_UTILITY_MAIN_THREAD_H_ + +#include <string> + +#include "base/threading/thread.h" +#include "content/common/content_export.h" + +namespace content { + +class ChildProcess; + +class UtilityMainThread : public base::Thread { + public: + UtilityMainThread(const std::string& channel_id); + virtual ~UtilityMainThread(); + private: + + // base::Thread implementation: + virtual void Init() OVERRIDE; + virtual void CleanUp() OVERRIDE; + + void InitInternal(); + + std::string channel_id_; + scoped_ptr<ChildProcess> child_process_; + + DISALLOW_COPY_AND_ASSIGN(UtilityMainThread); +}; + +CONTENT_EXPORT base::Thread* CreateUtilityMainThread( + const std::string& channel_id); + +} // namespace content + +#endif // CONTENT_UTILITY_UTILITY_MAIN_THREAD_H_ |