Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(535)

Unified Diff: content/browser/utility_process_host_impl.cc

Issue 18119009: Make utility process run in-process when running in single-process mode. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: undo unnecessary changes Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/utility_process_host_impl.h ('k') | content/content.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/utility_process_host_impl.cc
===================================================================
--- content/browser/utility_process_host_impl.cc (revision 210446)
+++ content/browser/utility_process_host_impl.cc (working copy)
@@ -7,15 +7,24 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
+#include "base/lazy_instance.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/synchronization/lock.h"
+#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"
#include "content/public/browser/content_browser_client.h"
#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"
#include "webkit/plugins/plugin_switches.h"
@@ -45,6 +54,51 @@
};
#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;
+
+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);
+};
+
UtilityProcessHost* UtilityProcessHost::Create(
UtilityProcessHostClient* client,
base::SequencedTaskRunner* client_task_runner) {
@@ -65,7 +119,6 @@
#endif
use_linux_zygote_(false),
started_(false) {
- process_.reset(new BrowserChildProcessHostImpl(PROCESS_TYPE_UTILITY, this));
}
UtilityProcessHostImpl::~UtilityProcessHostImpl() {
@@ -124,79 +177,88 @@
if (is_batch_mode_)
return true;
+
// Name must be set or metrics_service will crash in any test which
// launches a UtilityProcessHost.
+ process_.reset(new BrowserChildProcessHostImpl(PROCESS_TYPE_UTILITY, this));
process_->SetName(ASCIIToUTF16("utility process"));
std::string channel_id = process_->GetHost()->CreateChannel();
if (channel_id.empty())
return false;
- const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
- int child_flags = child_flags_;
+ if (RenderProcessHost::run_renderer_in_process()) {
+ // 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_->Start();
+ } else {
+ const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
+ int child_flags = child_flags_;
#if defined(OS_POSIX)
- bool has_cmd_prefix = browser_command_line.HasSwitch(
- switches::kUtilityCmdPrefix);
+ bool has_cmd_prefix = browser_command_line.HasSwitch(
+ switches::kUtilityCmdPrefix);
- // When running under gdb, forking /proc/self/exe ends up forking the gdb
- // executable instead of Chromium. It is almost safe to assume that no
- // updates will happen while a developer is running with
- // |switches::kUtilityCmdPrefix|. See ChildProcessHost::GetChildPath() for
- // a similar case with Valgrind.
- if (has_cmd_prefix)
- child_flags = ChildProcessHost::CHILD_NORMAL;
+ // When running under gdb, forking /proc/self/exe ends up forking the gdb
+ // executable instead of Chromium. It is almost safe to assume that no
+ // updates will happen while a developer is running with
+ // |switches::kUtilityCmdPrefix|. See ChildProcessHost::GetChildPath() for
+ // a similar case with Valgrind.
+ if (has_cmd_prefix)
+ child_flags = ChildProcessHost::CHILD_NORMAL;
#endif
- base::FilePath exe_path = ChildProcessHost::GetChildPath(child_flags);
- if (exe_path.empty()) {
- NOTREACHED() << "Unable to get utility process binary name.";
- return false;
- }
+ base::FilePath exe_path = ChildProcessHost::GetChildPath(child_flags);
+ if (exe_path.empty()) {
+ NOTREACHED() << "Unable to get utility process binary name.";
+ return false;
+ }
- CommandLine* cmd_line = new CommandLine(exe_path);
- cmd_line->AppendSwitchASCII(switches::kProcessType,
- switches::kUtilityProcess);
- cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id);
- std::string locale = GetContentClient()->browser()->GetApplicationLocale();
- cmd_line->AppendSwitchASCII(switches::kLang, locale);
+ CommandLine* cmd_line = new CommandLine(exe_path);
+ cmd_line->AppendSwitchASCII(switches::kProcessType,
+ switches::kUtilityProcess);
+ cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id);
+ std::string locale = GetContentClient()->browser()->GetApplicationLocale();
+ cmd_line->AppendSwitchASCII(switches::kLang, locale);
- if (no_sandbox_ || browser_command_line.HasSwitch(switches::kNoSandbox))
- cmd_line->AppendSwitch(switches::kNoSandbox);
+ if (no_sandbox_ || browser_command_line.HasSwitch(switches::kNoSandbox))
+ cmd_line->AppendSwitch(switches::kNoSandbox);
#if defined(OS_MACOSX)
- if (browser_command_line.HasSwitch(switches::kEnableSandboxLogging))
- cmd_line->AppendSwitch(switches::kEnableSandboxLogging);
+ if (browser_command_line.HasSwitch(switches::kEnableSandboxLogging))
+ cmd_line->AppendSwitch(switches::kEnableSandboxLogging);
#endif
- if (browser_command_line.HasSwitch(switches::kDebugPluginLoading))
- cmd_line->AppendSwitch(switches::kDebugPluginLoading);
+ if (browser_command_line.HasSwitch(switches::kDebugPluginLoading))
+ cmd_line->AppendSwitch(switches::kDebugPluginLoading);
#if defined(OS_POSIX)
- // TODO(port): Sandbox this on Linux. Also, zygote this to work with
- // Linux updating.
- if (has_cmd_prefix) {
- // launch the utility child process with some prefix (usually "xterm -e gdb
- // --args").
- cmd_line->PrependWrapper(browser_command_line.GetSwitchValueNative(
- switches::kUtilityCmdPrefix));
- }
+ // TODO(port): Sandbox this on Linux. Also, zygote this to work with
+ // Linux updating.
+ if (has_cmd_prefix) {
+ // launch the utility child process with some prefix (usually "xterm -e gdb
+ // --args").
+ cmd_line->PrependWrapper(browser_command_line.GetSwitchValueNative(
+ switches::kUtilityCmdPrefix));
+ }
- cmd_line->AppendSwitchPath(switches::kUtilityProcessAllowedDir, exposed_dir_);
+ cmd_line->AppendSwitchPath(switches::kUtilityProcessAllowedDir, exposed_dir_);
#endif
- bool use_zygote = false;
+ bool use_zygote = false;
#if defined(OS_LINUX)
- use_zygote = !no_sandbox_ && use_linux_zygote_;
+ use_zygote = !no_sandbox_ && use_linux_zygote_;
#endif
- process_->Launch(
+ process_->Launch(
#if defined(OS_WIN)
- new UtilitySandboxedProcessLauncherDelegate(exposed_dir_),
+ new UtilitySandboxedProcessLauncherDelegate(exposed_dir_),
#elif defined(OS_POSIX)
- use_zygote,
- env_,
+ use_zygote,
+ env_,
#endif
- cmd_line);
+ cmd_line);
+ }
return true;
}
« no previous file with comments | « content/browser/utility_process_host_impl.h ('k') | content/content.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698