summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorscottmg@chromium.org <scottmg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-16 07:45:36 +0000
committerscottmg@chromium.org <scottmg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-16 07:45:36 +0000
commitd7a2d89aee556017139f6bea76e328423e60277d (patch)
tree018c1358276c3c551e888568f1a0e19ab840da25
parented522c341e491b8aad34f3ac2d9c06669971627e (diff)
downloadchromium_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
-rw-r--r--build/common.gypi3
-rw-r--r--chrome/app/chrome_main_delegate.cc8
-rw-r--r--chrome/chrome_exe.gypi3
-rw-r--r--content/app/content_main_runner.cc13
-rw-r--r--content/browser/DEPS4
-rw-r--r--content/browser/gpu/gpu_process_host.cc54
-rw-r--r--content/browser/gpu/gpu_process_host.h9
-rw-r--r--content/browser/renderer_host/DEPS4
-rw-r--r--content/browser/renderer_host/render_process_host_impl.cc85
-rw-r--r--content/browser/renderer_host/render_process_host_impl.h4
-rw-r--r--content/browser/utility_process_host_impl.cc64
-rw-r--r--content/browser/utility_process_host_impl.h6
-rw-r--r--content/content_gpu.gypi2
-rw-r--r--content/content_renderer.gypi2
-rw-r--r--content/content_tests.gypi1
-rw-r--r--content/content_utility.gypi2
-rw-r--r--content/gpu/gpu_main_thread.cc37
-rw-r--r--content/gpu/gpu_main_thread.h38
-rw-r--r--content/public/browser/render_process_host.h6
-rw-r--r--content/public/browser/utility_process_host.h7
-rw-r--r--content/public/test/content_test_suite_base.cc13
-rw-r--r--content/renderer/renderer_main_thread.cc45
-rw-r--r--content/renderer/renderer_main_thread.h39
-rw-r--r--content/utility/utility_main_thread.cc50
-rw-r--r--content/utility/utility_main_thread.h40
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_