diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-21 20:01:31 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-21 20:01:31 +0000 |
commit | 8cd77dc30ea2528c7190b4e4629e560118d568b6 (patch) | |
tree | dd2f2e2f3d1f39efd0474823455a78a86a246c26 /chrome | |
parent | 2fec49dae9e67e1133d8884627c05f74c6ac3e59 (diff) | |
download | chromium_src-8cd77dc30ea2528c7190b4e4629e560118d568b6.zip chromium_src-8cd77dc30ea2528c7190b4e4629e560118d568b6.tar.gz chromium_src-8cd77dc30ea2528c7190b4e4629e560118d568b6.tar.bz2 |
POSIX: Get render_process_host to build.
This is an adopted CL from Evan. Original:
http://codereview.chromium.org/14504
(see original for review comments etc)
Review URL: http://codereview.chromium.org/16814
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8384 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/browser.scons | 6 | ||||
-rw-r--r-- | chrome/browser/cache_manager_host.h | 6 | ||||
-rw-r--r-- | chrome/browser/plugin_service.h | 4 | ||||
-rw-r--r-- | chrome/browser/render_widget_helper.h | 2 | ||||
-rw-r--r-- | chrome/browser/renderer_host/browser_render_process_host.cc | 129 | ||||
-rw-r--r-- | chrome/browser/renderer_host/browser_render_process_host.h | 35 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_process_host.cc | 11 | ||||
-rw-r--r-- | chrome/browser/resource_message_filter.h | 3 | ||||
-rw-r--r-- | chrome/browser/visitedlink_master.h | 1 | ||||
-rw-r--r-- | chrome/renderer/render_process.h | 3 |
10 files changed, 124 insertions, 76 deletions
diff --git a/chrome/browser/browser.scons b/chrome/browser/browser.scons index e33cfa3..84917e2 100644 --- a/chrome/browser/browser.scons +++ b/chrome/browser/browser.scons @@ -548,8 +548,8 @@ input_files = ChromeFileList([ 'renderer_host/download_resource_handler.h', 'renderer_host/download_throttling_resource_handler.cc', 'renderer_host/download_throttling_resource_handler.h', - 'renderer_host/render_process_host.cc', - 'renderer_host/render_process_host.h', + 'renderer_host/browser_render_process_host.cc', + 'renderer_host/browser_render_process_host.h', 'renderer_host/resource_dispatcher_host.cc', 'renderer_host/resource_dispatcher_host.h', 'renderer_host/resource_handler.h', @@ -785,8 +785,6 @@ if not env.Bit('windows'): 'render_widget_helper.cc', 'render_widget_host.cc', 'renderer_host/cross_site_resource_handler.cc', - 'renderer_host/render_process_host.cc', - 'renderer_host/browser_render_process_host.cc', 'renderer_host/resource_dispatcher_host.cc', 'repost_form_warning_dialog.cc', 'resource_message_filter.cc', diff --git a/chrome/browser/cache_manager_host.h b/chrome/browser/cache_manager_host.h index d87cbf8..ba501d5 100644 --- a/chrome/browser/cache_manager_host.h +++ b/chrome/browser/cache_manager_host.h @@ -87,7 +87,7 @@ class CacheManagerHost { // This class is a singleton. Do not instantiate directly. CacheManagerHost(); - friend DefaultSingletonTraits<CacheManagerHost>; + friend struct DefaultSingletonTraits<CacheManagerHost>; ~CacheManagerHost(); @@ -137,8 +137,8 @@ class CacheManagerHost { // Get the amount of memory that would be required to implement |tactic| // using the specified allocation tactic. This function defines the // semantics for each of the tactics. - static size_t CacheManagerHost::GetSize(AllocationTactic tactic, - const CacheManager::UsageStats& stats); + static size_t GetSize(AllocationTactic tactic, + const CacheManager::UsageStats& stats); // Attempt to use the specified tactics to compute an allocation strategy // and place the result in |strategy|. |active_stats| and |inactive_stats| diff --git a/chrome/browser/plugin_service.h b/chrome/browser/plugin_service.h index c37b362..2ee90b7 100644 --- a/chrome/browser/plugin_service.h +++ b/chrome/browser/plugin_service.h @@ -175,8 +175,8 @@ class PluginProcessHostIterator { PluginProcessHostIterator& operator=( const PluginProcessHostIterator& instance) { - iterator_ = instance.iterator_; - return *this; + iterator_ = instance.iterator_; + return *this; } const PluginProcessHost* operator->() const { diff --git a/chrome/browser/render_widget_helper.h b/chrome/browser/render_widget_helper.h index fe2bf08..9ec75e0 100644 --- a/chrome/browser/render_widget_helper.h +++ b/chrome/browser/render_widget_helper.h @@ -112,7 +112,7 @@ class RenderWidgetHelper : // A class used to proxy a paint message. PaintMsgProxy objects are created // on the IO thread and destroyed on the UI thread. class PaintMsgProxy; - friend PaintMsgProxy; + friend class PaintMsgProxy; // Map from render_widget_id to live PaintMsgProxy instance. typedef base::hash_map<int, PaintMsgProxy*> PaintMsgProxyMap; diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index cb43eb9..6c9ab93 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -2,8 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Represents the browser side of the browser <--> renderer communication +// channel. There will be one RenderProcessHost per renderer process. + #include "chrome/browser/renderer_host/browser_render_process_host.h" +#include "build/build_config.h" + #include <algorithm> #include <sstream> #include <vector> @@ -18,22 +23,17 @@ #include "base/singleton.h" #include "base/string_util.h" #include "base/thread.h" -#include "base/win_util.h" #include "chrome/app/result_codes.h" -#include "chrome/browser/browser.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/cache_manager_host.h" #include "chrome/browser/extensions/user_script_master.h" #include "chrome/browser/history/history.h" #include "chrome/browser/plugin_service.h" #include "chrome/browser/render_widget_helper.h" -#include "chrome/browser/render_view_host.h" #include "chrome/browser/renderer_security_policy.h" #include "chrome/browser/resource_message_filter.h" -#include "chrome/browser/sandbox_policy.h" #include "chrome/browser/spellchecker.h" #include "chrome/browser/visitedlink_master.h" -#include "chrome/browser/tab_contents/web_contents.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/debug_flags.h" @@ -42,11 +42,21 @@ #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" #include "chrome/common/process_watcher.h" -#include "chrome/common/win_util.h" #include "chrome/renderer/render_process.h" #include "net/base/cookie_monster.h" #include "net/base/net_util.h" + +#if defined(OS_WIN) +// TODO(port): see comment by the only usage of RenderViewHost in this file. +#include "chrome/browser/render_view_host.h" + +// Once the above TODO is finished, then this block is all Windows-specific +// files. +#include "base/win_util.h" +#include "chrome/browser/sandbox_policy.h" +#include "chrome/common/win_util.h" #include "sandbox/src/sandbox.h" +#endif #include "SkBitmap.h" @@ -65,7 +75,9 @@ class RendererMainThread : public base::Thread { protected: virtual void Init() { +#if defined(OS_WIN) CoInitialize(NULL); +#endif bool rv = RenderProcess::GlobalInit(channel_id_); DCHECK(rv); @@ -80,7 +92,9 @@ class RendererMainThread : public base::Thread { virtual void CleanUp() { RenderProcess::GlobalCleanup(); +#if defined(OS_WIN) CoUninitialize(); +#endif } private: @@ -139,7 +153,6 @@ BrowserRenderProcessHost::~BrowserRenderProcessHost() { channel_.reset(); if (process_.handle() && !run_renderer_in_process()) { - watcher_.StopWatching(); ProcessWatcher::EnsureProcessTerminated(process_.handle()); } @@ -149,6 +162,27 @@ BrowserRenderProcessHost::~BrowserRenderProcessHost() { NOTIFY_USER_SCRIPTS_LOADED, NotificationService::AllSources()); } +// When we're started with the --start-renderers-manually flag, we pop up a +// modal dialog requesting the user manually start up a renderer. +// |cmd_line| is the command line to start the renderer with. +static void RunStartRenderersManuallyDialog(const CommandLine& cmd_line) { +#if defined(OS_WIN) + std::wstring message = + L"Please start a renderer process using:\n" + + cmd_line.command_line_string(); + + // We don't know the owner window for RenderProcessHost and therefore we + // pass a NULL HWND argument. + win_util::MessageBox(NULL, + message, + switches::kBrowserStartRenderersManually, + MB_OK); +#else + // TODO(port): refactor above code / pop up a message box here. + NOTIMPLEMENTED(); +#endif +} + bool BrowserRenderProcessHost::Init() { // calling Init() more than once does nothing, this makes it more convenient // for the view host which may not be sure in some cases @@ -170,7 +204,7 @@ bool BrowserRenderProcessHost::Init() { const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); // setup IPC channel - std::wstring channel_id = GenerateRandomChannelID(this); + const std::wstring channel_id = GenerateRandomChannelID(this); channel_.reset( new IPC::SyncChannel(channel_id, IPC::Channel::MODE_SERVER, this, resource_message_filter, @@ -226,7 +260,7 @@ bool BrowserRenderProcessHost::Init() { switches::kEnableVideo, }; - for (int i = 0; i < arraysize(switch_names); ++i) { + for (size_t i = 0; i < arraysize(switch_names); ++i) { if (browser_command_line.HasSwitch(switch_names[i])) { cmd_line.AppendSwitchWithValue(switch_names[i], browser_command_line.GetSwitchValue(switch_names[i])); @@ -243,10 +277,13 @@ bool BrowserRenderProcessHost::Init() { in_sandbox = false; } +#if defined(OS_WIN) bool child_needs_help = DebugFlags::ProcessDebugFlags(&cmd_line, DebugFlags::RENDERER, in_sandbox); +#endif + cmd_line.AppendSwitchWithValue(switches::kProcessType, switches::kRendererProcess); @@ -281,17 +318,9 @@ bool BrowserRenderProcessHost::Init() { if (g_browser_process->local_state() && g_browser_process->local_state()->GetBoolean( prefs::kStartRenderersManually)) { - std::wstring message = - L"Please start a renderer process using:\n" + - cmd_line.command_line_string(); - - // We don't know the owner window for BrowserRenderProcessHost and therefore we - // pass a NULL HWND argument. - win_util::MessageBox(NULL, - message, - switches::kBrowserStartRenderersManually, - MB_OK); + RunStartRenderersManuallyDialog(cmd_line); } else { +#if defined(OS_WIN) if (in_sandbox) { // spawn the child process in the sandbox sandbox::BrokerServices* broker_service = @@ -362,15 +391,22 @@ bool BrowserRenderProcessHost::Init() { // the process is in a sandbox. if (child_needs_help) DebugUtil::SpawnDebuggerOnProcess(target.dwProcessId); - } else { + } else +#endif // OS_WIN and sandbox + { +#if defined(OS_WIN) // spawn child process - HANDLE process; + base::ProcessHandle process = 0; + // TODO(port): LaunchApp is actually no good on POSIX when + // we've constructed the command line as we have here, as the above + // calls all append to a single string while LaunchApp reaches in to + // the argv array. CommandLine should be fixed, but once it is, this + // code will be correct. if (!base::LaunchApp(cmd_line, false, false, &process)) return false; process_.set_handle(process); +#endif } - - watcher_.StartWatching(process_.handle(), this); } } @@ -504,6 +540,7 @@ bool BrowserRenderProcessHost::FastShutdownIfPossible() { if (BrowserRenderProcessHost::run_renderer_in_process()) return false; // Since process mode can't do fast shutdown. +#if defined(OS_WIN) // Test if there's an unload listener BrowserRenderProcessHost::listeners_iterator iter; // NOTE: This is a bit dangerous. We know that for now, listeners are @@ -522,6 +559,13 @@ bool BrowserRenderProcessHost::FastShutdownIfPossible() { return false; } } +#else + // TODO(port): the above is the only reason this file pulls in + // RenderWidgetHost and RenderViewHost. + // Perhaps IPC::Channel::Listener needs another method like CanTerminate()? + // No matter what, some abstractions are getting broken here... + NOTIMPLEMENTED(); +#endif // Otherwise, we're allowed to just terminate the process. Using exit code 0 // means that UMA won't treat this as a renderer crash. @@ -574,16 +618,20 @@ void BrowserRenderProcessHost::OnMessageReceived(const IPC::Message& msg) { void BrowserRenderProcessHost::OnChannelConnected(int32 peer_pid) { // process_ is not NULL if we created the renderer process if (!process_.handle()) { - if (GetCurrentProcessId() == peer_pid) { + if (base::GetCurrentProcId() == peer_pid) { // We are in single-process mode. In theory we should have access to // ourself but it may happen that we don't. - process_.set_handle(GetCurrentProcess()); + process_.set_handle(base::GetCurrentProcessHandle()); } else { +#if defined(OS_WIN) // Request MAXIMUM_ALLOWED to match the access a handle // returned by CreateProcess() has to the process object. process_.set_handle(OpenProcess(MAXIMUM_ALLOWED, FALSE, peer_pid)); +#elif defined(OS_POSIX) + // ProcessHandle is just a pid. + process_.set_handle(peer_pid); +#endif DCHECK(process_.handle()); - watcher_.StartWatching(process_.handle(), this); } } else { // Need to verify that the peer_pid is actually the process we know, if @@ -594,23 +642,25 @@ void BrowserRenderProcessHost::OnChannelConnected(int32 peer_pid) { // Static. This function can be called from the IO Thread or from the UI thread. void BrowserRenderProcessHost::BadMessageTerminateProcess(uint16 msg_type, - HANDLE process) { + base::ProcessHandle process) { LOG(ERROR) << "bad message " << msg_type << " terminating renderer."; if (BrowserRenderProcessHost::run_renderer_in_process()) { // In single process mode it is better if we don't suicide but just crash. CHECK(false); } NOTREACHED(); - ::TerminateProcess(process, ResultCodes::KILLED_BAD_MESSAGE); + base::KillProcess(process, ResultCodes::KILLED_BAD_MESSAGE, false); } -// indicates the renderer process has exited -void BrowserRenderProcessHost::OnObjectSignaled(HANDLE object) { +void BrowserRenderProcessHost::OnChannelError() { + // 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. + DCHECK(process_.handle()); DCHECK(channel_.get()); - DCHECK_EQ(object, process_.handle()); + base::ProcessHandle process = process_.handle(); - bool clean_shutdown = !base::DidProcessCrash(object); + bool clean_shutdown = !base::DidProcessCrash(process); process_.Close(); @@ -629,7 +679,7 @@ void BrowserRenderProcessHost::OnObjectSignaled(HANDLE object) { // deleted. We therefore need a stack copy of the web view list to avoid // crashing when checking for the termination condition the last time. IDMap<IPC::Channel::Listener> local_listeners(listeners_); - for (IDMap<IPC::Channel::Listener>::const_iterator i = local_listeners.begin(); + for (listeners_iterator i = local_listeners.begin(); i != local_listeners.end(); ++i) { i->second->OnMessageReceived(ViewHostMsg_RendererGone(i->first)); } @@ -725,3 +775,16 @@ void BrowserRenderProcessHost::Observe(NotificationType type, } } } + +std::wstring GenerateRandomChannelID(void* instance) { + // Note: the string must start with the current process id, this is how + // child processes determine the pid of the parent. + // Build the channel ID. This is composed of a unique identifier for the + // parent browser process, an identifier for the renderer/plugin instance, + // and a random component. We use a random component so that a hacked child + // process can't cause denial of service by causing future named pipe creation + // to fail. + return StringPrintf(L"%d.%x.%d", + base::GetCurrentProcId(), instance, + base::RandInt(0, std::numeric_limits<int>::max())); +} diff --git a/chrome/browser/renderer_host/browser_render_process_host.h b/chrome/browser/renderer_host/browser_render_process_host.h index 2f766df..70c085c 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.h +++ b/chrome/browser/renderer_host/browser_render_process_host.h @@ -5,16 +5,20 @@ #ifndef CHROME_BROWSER_RENDERER_HOST_BROWSER_RENDER_PROCESS_HOST_H_ #define CHROME_BROWSER_RENDERER_HOST_BROWSER_RENDER_PROCESS_HOST_H_ +#include "build/build_config.h" + +#if defined(OS_WIN) +#include <windows.h> +#endif + #include <limits> #include <set> #include <vector> -#include <windows.h> #include "base/id_map.h" -#include "base/object_watcher.h" +#include "base/process.h" #include "base/rand_util.h" #include "base/ref_counted.h" -#include "base/scoped_handle.h" #include "base/scoped_ptr.h" #include "chrome/browser/renderer_host/render_process_host.h" #include "chrome/common/notification_service.h" @@ -43,7 +47,6 @@ class Thread; // are correlated with IDs. This way, the Views and the corresponding ViewHosts // communicate through the two process objects. class BrowserRenderProcessHost : public RenderProcessHost, - public base::ObjectWatcher::Delegate, public NotificationObserver { public: explicit BrowserRenderProcessHost(Profile* profile); @@ -70,16 +73,15 @@ class BrowserRenderProcessHost : public RenderProcessHost, // IPC::Channel::Listener via RenderProcessHost. virtual void OnMessageReceived(const IPC::Message& msg); virtual void OnChannelConnected(int32 peer_pid); + virtual void OnChannelError(); static void RegisterPrefs(PrefService* prefs); // If the a process has sent a message that cannot be decoded, it is deemed // corrupted and thus needs to be terminated using this call. This function // can be safely called from any thread. - static void BadMessageTerminateProcess(uint16 msg_type, HANDLE renderer); - - // ObjectWatcher::Delegate - virtual void OnObjectSignaled(HANDLE object); + static void BadMessageTerminateProcess(uint16 msg_type, + base::ProcessHandle renderer); // NotificationObserver implementation. virtual void Observe(NotificationType type, @@ -122,9 +124,6 @@ class BrowserRenderProcessHost : public RenderProcessHost, // Returns true if the priority is backgrounded; false otherwise. void SetBackgrounded(bool boost); - // Used to watch the renderer process handle. - base::ObjectWatcher watcher_; - // The count of currently visible widgets. Since the host can be a container // for multiple widgets, it uses this count to determine when it should be // backgrounded. @@ -142,19 +141,7 @@ class BrowserRenderProcessHost : public RenderProcessHost, // Generates a unique channel name for a child renderer/plugin process. // The "instance" pointer value is baked into the channel id. -inline std::wstring GenerateRandomChannelID(void* instance) { - // Note: the string must start with the current process id, this is how - // child processes determine the pid of the parent. - // Build the channel ID. This is composed of a unique identifier for the - // parent browser process, an identifier for the renderer/plugin instance, - // and a random component. We use a random component so that a hacked child - // process can't cause denial of service by causing future named pipe creation - // to fail. - return StringPrintf(L"%d.%x.%d", - GetCurrentProcessId(), instance, - base::RandInt(0, std::numeric_limits<int>::max())); -} - +std::wstring GenerateRandomChannelID(void* instance); #endif // CHROME_BROWSER_RENDERER_HOST_BROWSER_RENDER_PROCESS_HOST_H_ diff --git a/chrome/browser/renderer_host/render_process_host.cc b/chrome/browser/renderer_host/render_process_host.cc index 18323f4..3ec8328 100644 --- a/chrome/browser/renderer_host/render_process_host.cc +++ b/chrome/browser/renderer_host/render_process_host.cc @@ -12,10 +12,11 @@ namespace { unsigned int GetMaxRendererProcessCount() { - // Defines the maximum number of renderer processes according to the amount - // of installed memory as reported by the OS. The table values are calculated - // by assuming that you want the renderers to use half of the installed ram - // and assuming that each tab uses ~25MB. + // Defines the maximum number of renderer processes according to the + // amount of installed memory as reported by the OS. The table + // values are calculated by assuming that you want the renderers to + // use half of the installed ram and assuming that each tab uses + // ~25MB. static const int kMaxRenderersByRamTier[] = { 4, // less than 256MB 8, // 256MB @@ -25,7 +26,7 @@ unsigned int GetMaxRendererProcessCount() { static unsigned int max_count = 0; if (!max_count) { - int memory_tier = base::SysInfo::AmountOfPhysicalMemoryMB() / 256; + size_t memory_tier = base::SysInfo::AmountOfPhysicalMemoryMB() / 256; if (memory_tier >= arraysize(kMaxRenderersByRamTier)) max_count = chrome::kMaxRendererProcessCount; else diff --git a/chrome/browser/resource_message_filter.h b/chrome/browser/resource_message_filter.h index 640b138..0d353da 100644 --- a/chrome/browser/resource_message_filter.h +++ b/chrome/browser/resource_message_filter.h @@ -104,9 +104,12 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, const std::wstring& filter, uint32 user_data); +#if defined(OS_WIN) // Cache fonts for the renderer. See ResourceMessageFilter::OnLoadFont // implementation for more details void OnLoadFont(LOGFONT font); +#endif + void OnGetScreenInfo(gfx::NativeView window, webkit_glue::ScreenInfo* results); void OnGetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins); diff --git a/chrome/browser/visitedlink_master.h b/chrome/browser/visitedlink_master.h index 8c0af4b..ac99634 100644 --- a/chrome/browser/visitedlink_master.h +++ b/chrome/browser/visitedlink_master.h @@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_VISITEDLINK_MASTER_H__ #define CHROME_BROWSER_VISITEDLINK_MASTER_H__ -#include <windows.h> #include <set> #include <string> #include <vector> diff --git a/chrome/renderer/render_process.h b/chrome/renderer/render_process.h index bdba635..8f2fdbc 100644 --- a/chrome/renderer/render_process.h +++ b/chrome/renderer/render_process.h @@ -5,9 +5,6 @@ #ifndef CHROME_RENDERER_RENDER_PROCESS_H__ #define CHROME_RENDERER_RENDER_PROCESS_H__ -#include <objidl.h> -#include <mlang.h> - #include "base/shared_memory.h" #include "chrome/common/child_process.h" #include "chrome/renderer/render_thread.h" |