summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkbr@google.com <kbr@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-06 23:25:50 +0000
committerkbr@google.com <kbr@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-06 23:25:50 +0000
commita363c7abfdc3e6562ae7f4fe338f585192f347b4 (patch)
tree9bc04bbc6a7ac5c39946820e470f3fb00873afec
parent35312bf28d33672dbb69afe28dd82c92411ef100 (diff)
downloadchromium_src-a363c7abfdc3e6562ae7f4fe338f585192f347b4.zip
chromium_src-a363c7abfdc3e6562ae7f4fe338f585192f347b4.tar.gz
chromium_src-a363c7abfdc3e6562ae7f4fe338f585192f347b4.tar.bz2
Revert http://codereview.chromium.org/6094009 (r70768) due to
compilation error on Mac OS X. BUG=65369 TBR=apatrick TEST=none Review URL: http://codereview.chromium.org/6150001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@70681 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/gpu_process_host.cc30
-rw-r--r--chrome/browser/gpu_process_host.h5
-rw-r--r--chrome/common/gpu_messages_internal.h8
-rw-r--r--chrome/gpu/gpu_main.cc89
-rw-r--r--chrome/gpu/gpu_thread.cc124
-rw-r--r--chrome/gpu/gpu_thread.h11
6 files changed, 104 insertions, 163 deletions
diff --git a/chrome/browser/gpu_process_host.cc b/chrome/browser/gpu_process_host.cc
index 8e7ac68..b0d7931 100644
--- a/chrome/browser/gpu_process_host.cc
+++ b/chrome/browser/gpu_process_host.cc
@@ -97,9 +97,6 @@ bool GpuProcessHost::EnsureInitialized() {
if (!initialized_) {
initialized_ = true;
initialized_successfully_ = Init();
- if (initialized_successfully_) {
- Send(new GpuMsg_Initialize());
- }
}
return initialized_successfully_;
}
@@ -231,13 +228,10 @@ void GpuProcessHost::OnChannelEstablished(
}
void GpuProcessHost::OnSynchronizeReply() {
- // Guard against race conditions in abrupt GPU process termination.
- if (queued_synchronization_replies_.size() > 0) {
- const SynchronizationRequest& request =
- queued_synchronization_replies_.front();
- SendSynchronizationReply(request.reply, request.filter);
- queued_synchronization_replies_.pop();
- }
+ const SynchronizationRequest& request =
+ queued_synchronization_replies_.front();
+ SendSynchronizationReply(request.reply, request.filter);
+ queued_synchronization_replies_.pop();
}
#if defined(OS_LINUX)
@@ -486,26 +480,11 @@ void GpuProcessHost::SendSynchronizationReply(
filter->Send(reply);
}
-void GpuProcessHost::SendOutstandingReplies() {
- // First send empty channel handles for all EstablishChannel requests.
- while (!sent_requests_.empty()) {
- const ChannelRequest& request = sent_requests_.front();
- SendEstablishChannelReply(IPC::ChannelHandle(), GPUInfo(), request.filter);
- sent_requests_.pop();
- }
-
- // Now unblock all renderers waiting for synchronization replies.
- while (!queued_synchronization_replies_.empty()) {
- OnSynchronizeReply();
- }
-}
-
bool GpuProcessHost::CanShutdown() {
return true;
}
void GpuProcessHost::OnChildDied() {
- SendOutstandingReplies();
// Located in OnChildDied because OnProcessCrashed suffers from a race
// condition on Linux. The GPU process will only die if it crashes.
UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents",
@@ -514,7 +493,6 @@ void GpuProcessHost::OnChildDied() {
}
void GpuProcessHost::OnProcessCrashed(int exit_code) {
- SendOutstandingReplies();
if (++g_gpu_crash_count >= kGpuMaxCrashCount) {
// The gpu process is too unstable to use. Disable it for current session.
RenderViewHostDelegateHelper::set_gpu_enabled(false);
diff --git a/chrome/browser/gpu_process_host.h b/chrome/browser/gpu_process_host.h
index 9a7a90d..e3bc66a 100644
--- a/chrome/browser/gpu_process_host.h
+++ b/chrome/browser/gpu_process_host.h
@@ -107,11 +107,6 @@ class GpuProcessHost : public BrowserChildProcessHost,
void SendSynchronizationReply(IPC::Message* reply,
RenderMessageFilter* filter);
- // Sends outstanding replies to renderer processes. This is only called
- // in error situations like the GPU process crashing -- but is necessary
- // to prevent the renderer process from hanging.
- void SendOutstandingReplies();
-
virtual bool CanShutdown();
virtual void OnChildDied();
virtual void OnProcessCrashed(int exit_code);
diff --git a/chrome/common/gpu_messages_internal.h b/chrome/common/gpu_messages_internal.h
index 22da39a..22f2f9d 100644
--- a/chrome/common/gpu_messages_internal.h
+++ b/chrome/common/gpu_messages_internal.h
@@ -25,14 +25,6 @@ class GPUInfo;
//------------------------------------------------------------------------------
// GPU Messages
// These are messages from the browser to the GPU process.
-
-// Tells the GPU process to initialize itself. The browser explicitly
-// requests this be done so that we are guaranteed that the channel is set
-// up between the browser and GPU process before doing any work that might
-// potentially crash the GPU process. Detection of the child process
-// exiting abruptly is predicated on having the IPC channel set up.
-IPC_MESSAGE_CONTROL0(GpuMsg_Initialize)
-
// Tells the GPU process to create a new channel for communication with a
// given renderer. The channel name is returned in a
// GpuHostMsg_ChannelEstablished message. The renderer ID is passed so that
diff --git a/chrome/gpu/gpu_main.cc b/chrome/gpu/gpu_main.cc
index 9bd6568..5d0e090 100644
--- a/chrome/gpu/gpu_main.cc
+++ b/chrome/gpu/gpu_main.cc
@@ -4,6 +4,9 @@
#include <stdlib.h>
+#include "app/app_switches.h"
+#include "app/gfx/gl/gl_context.h"
+#include "app/gfx/gl/gl_implementation.h"
#include "app/win/scoped_com_initializer.h"
#include "base/environment.h"
#include "base/message_loop.h"
@@ -17,6 +20,7 @@
#include "chrome/gpu/gpu_config.h"
#include "chrome/gpu/gpu_process.h"
#include "chrome/gpu/gpu_thread.h"
+#include "chrome/gpu/gpu_watchdog_thread.h"
#if defined(USE_LINUX_BREAKPAD)
#include "chrome/app/breakpad_linux.h"
@@ -24,12 +28,31 @@
#if defined(OS_MACOSX)
#include "chrome/common/chrome_application_mac.h"
+#include "chrome/common/sandbox_mac.h"
#endif
#if defined(USE_X11)
#include "gfx/gtk_util.h"
#endif
+const int kGpuTimeout = 10000;
+
+namespace {
+
+bool InitializeGpuSandbox() {
+#if defined(OS_MACOSX)
+ CommandLine* parsed_command_line = CommandLine::ForCurrentProcess();
+ SandboxInitWrapper sandbox_wrapper;
+ return sandbox_wrapper.InitializeSandbox(*parsed_command_line,
+ switches::kGpuProcess);
+#else
+ // TODO(port): Create GPU sandbox for linux and windows.
+ return true;
+#endif
+}
+
+} // namespace
+
// Main function for starting the Gpu process.
int GpuMain(const MainFunctionParams& parameters) {
base::Time start_time = base::Time::Now();
@@ -63,21 +86,69 @@ int GpuMain(const MainFunctionParams& parameters) {
gfx::GtkInitFromCommandLine(command_line);
#endif
- // We can not tolerate early returns from this code, because the
- // detection of early return of a child process is implemented using
- // an IPC channel error. If the IPC channel is not fully set up
- // between the browser and GPU process, and the GPU process crashes
- // or exits early, the browser process will never detect it. For
- // this reason we defer all work related to the GPU until receiving
- // the GpuMsg_Initialize message from the browser.
+ // Note that kNoSandbox will also disable the GPU sandbox.
+ bool no_gpu_sandbox = command_line.HasSwitch(switches::kNoGpuSandbox);
+ if (!no_gpu_sandbox) {
+ if (!InitializeGpuSandbox()) {
+ LOG(ERROR) << "Failed to initialize the GPU sandbox";
+ return EXIT_FAILURE;
+ }
+ } else {
+ LOG(ERROR) << "Running without GPU sandbox";
+ }
+
+ // Load the GL implementation and locate the bindings before starting the GPU
+ // watchdog because this can take a lot of time and the GPU watchdog might
+ // terminate the GPU process.
+ if (!gfx::GLContext::InitializeOneOff())
+ return EXIT_FAILURE;
+
+ // Do this soon before running the message loop so accurate
+ // initialization time is recorded in the GPU info. Don't do it before
+ // starting the watchdog thread since it can take a significant amount of
+ // time to collect GPU information in GpuThread::Init.
GpuProcess gpu_process;
- GpuThread* gpu_thread = new GpuThread(command_line);
+ GpuThread* gpu_thread = new GpuThread;
gpu_thread->Init(start_time);
gpu_process.set_main_thread(gpu_thread);
+
+ // In addition to disabling the watchdog if the command line switch is
+ // present, disable it in two other cases. OSMesa is expected to run very
+ // slowly. Also disable the watchdog on valgrind because the code is expected
+ // to run slowly in that case.
+ bool enable_watchdog =
+ !command_line.HasSwitch(switches::kDisableGpuWatchdog) &&
+ gfx::GetGLImplementation() != gfx::kGLImplementationOSMesaGL &&
+ !RunningOnValgrind();
+
+ // Disable the watchdog in debug builds because they tend to only be run by
+ // developers who will not appreciate the watchdog killing the GPU process.
+#ifndef NDEBUG
+ enable_watchdog = false;
+#endif
+
+ // Disable the watchdog for Windows. It tends to abort when the GPU process
+ // is not hung but still taking a long time to do something. Instead, the
+ // browser process displays a dialog when it notices that the child window
+ // is hung giving the user an opportunity to terminate it. This is the
+ // same mechanism used to abort hung plugins.
+#if defined(OS_WIN)
+ enable_watchdog = false;
+#endif
+
+ // Start the GPU watchdog only after anything that is expected to be time
+ // consuming has completed, otherwise the process is liable to be aborted.
+ scoped_refptr<GpuWatchdogThread> watchdog_thread;
+ if (enable_watchdog) {
+ watchdog_thread = new GpuWatchdogThread(kGpuTimeout);
+ watchdog_thread->Start();
+ }
+
main_message_loop.Run();
- gpu_thread->StopWatchdog();
+ if (enable_watchdog)
+ watchdog_thread->Stop();
return 0;
}
diff --git a/chrome/gpu/gpu_thread.cc b/chrome/gpu/gpu_thread.cc
index f204ab1..c72de9e 100644
--- a/chrome/gpu/gpu_thread.cc
+++ b/chrome/gpu/gpu_thread.cc
@@ -8,49 +8,41 @@
#include <vector>
#include "app/gfx/gl/gl_context.h"
-#include "app/gfx/gl/gl_implementation.h"
#include "app/win/scoped_com_initializer.h"
#include "base/command_line.h"
#include "base/threading/worker_pool.h"
#include "build/build_config.h"
#include "chrome/common/child_process.h"
#include "chrome/common/child_process_logging.h"
-#include "chrome/common/chrome_switches.h"
#include "chrome/common/gpu_messages.h"
#include "chrome/gpu/gpu_info_collector.h"
-#include "chrome/gpu/gpu_watchdog_thread.h"
#include "ipc/ipc_channel_handle.h"
-#if defined(OS_MACOSX)
-#include "chrome/common/sandbox_mac.h"
-#endif
-
-const int kGpuTimeout = 10000;
-
-namespace {
-
-bool InitializeGpuSandbox() {
-#if defined(OS_MACOSX)
- CommandLine* parsed_command_line = CommandLine::ForCurrentProcess();
- SandboxInitWrapper sandbox_wrapper;
- return sandbox_wrapper.InitializeSandbox(*parsed_command_line,
- switches::kGpuProcess);
-#else
- // TODO(port): Create GPU sandbox for linux and windows.
- return true;
-#endif
+GpuThread::GpuThread() {
}
-} // namespace
-
-GpuThread::GpuThread(const CommandLine& command_line)
- : command_line_(command_line) {}
-
GpuThread::~GpuThread() {
}
void GpuThread::Init(const base::Time& process_start_time) {
- process_start_time_ = process_start_time;
+ gpu_info_collector::CollectGraphicsInfo(&gpu_info_);
+ child_process_logging::SetGpuInfo(gpu_info_);
+
+#if defined(OS_WIN)
+ // Asynchronously collect the DirectX diagnostics because this can take a
+ // couple of seconds.
+ if (!base::WorkerPool::PostTask(
+ FROM_HERE,
+ NewRunnableFunction(&GpuThread::CollectDxDiagnostics, this),
+ true)) {
+ // Flag GPU info as complete if the DirectX diagnostics cannot be collected.
+ gpu_info_.SetProgress(GPUInfo::kComplete);
+ }
+#endif
+
+ // Record initialization only after collecting the GPU info because that can
+ // take a significant amount of time.
+ gpu_info_.SetInitializationTime(base::Time::Now() - process_start_time);
}
void GpuThread::RemoveChannel(int renderer_id) {
@@ -61,7 +53,6 @@ bool GpuThread::OnControlMessageReceived(const IPC::Message& msg) {
bool msg_is_ok = true;
bool handled = true;
IPC_BEGIN_MESSAGE_MAP_EX(GpuThread, msg, msg_is_ok)
- IPC_MESSAGE_HANDLER(GpuMsg_Initialize, OnInitialize)
IPC_MESSAGE_HANDLER(GpuMsg_EstablishChannel, OnEstablishChannel)
IPC_MESSAGE_HANDLER(GpuMsg_CloseChannel, OnCloseChannel)
IPC_MESSAGE_HANDLER(GpuMsg_Synchronize, OnSynchronize)
@@ -79,83 +70,6 @@ bool GpuThread::OnControlMessageReceived(const IPC::Message& msg) {
return handled;
}
-void GpuThread::OnInitialize() {
- // Load the GL implementation and locate the bindings before starting the GPU
- // watchdog because this can take a lot of time and the GPU watchdog might
- // terminate the GPU process.
- if (!gfx::GLContext::InitializeOneOff()) {
- MessageLoop::current()->Quit();
- return;
- }
- gpu_info_collector::CollectGraphicsInfo(&gpu_info_);
- child_process_logging::SetGpuInfo(gpu_info_);
-
-#if defined(OS_WIN)
- // Asynchronously collect the DirectX diagnostics because this can take a
- // couple of seconds.
- if (!base::WorkerPool::PostTask(
- FROM_HERE,
- NewRunnableFunction(&GpuThread::CollectDxDiagnostics, this),
- true)) {
- // Flag GPU info as complete if the DirectX diagnostics cannot be collected.
- gpu_info_.SetProgress(GPUInfo::kComplete);
- }
-#endif
-
- // Record initialization only after collecting the GPU info because that can
- // take a significant amount of time.
- gpu_info_.SetInitializationTime(base::Time::Now() - process_start_time_);
-
- // Note that kNoSandbox will also disable the GPU sandbox.
- bool no_gpu_sandbox = command_line_.HasSwitch(switches::kNoGpuSandbox);
- if (!no_gpu_sandbox) {
- if (!InitializeGpuSandbox()) {
- LOG(ERROR) << "Failed to initialize the GPU sandbox";
- MessageLoop::current()->Quit();
- return;
- }
- } else {
- LOG(ERROR) << "Running without GPU sandbox";
- }
-
- // In addition to disabling the watchdog if the command line switch is
- // present, disable it in two other cases. OSMesa is expected to run very
- // slowly. Also disable the watchdog on valgrind because the code is expected
- // to run slowly in that case.
- bool enable_watchdog =
- !command_line_.HasSwitch(switches::kDisableGpuWatchdog) &&
- gfx::GetGLImplementation() != gfx::kGLImplementationOSMesaGL &&
- !RunningOnValgrind();
-
- // Disable the watchdog in debug builds because they tend to only be run by
- // developers who will not appreciate the watchdog killing the GPU process.
-#ifndef NDEBUG
- enable_watchdog = false;
-#endif
-
- // Disable the watchdog for Windows. It tends to abort when the GPU process
- // is not hung but still taking a long time to do something. Instead, the
- // browser process displays a dialog when it notices that the child window
- // is hung giving the user an opportunity to terminate it. This is the
- // same mechanism used to abort hung plugins.
-#if defined(OS_WIN)
- enable_watchdog = false;
-#endif
-
- // Start the GPU watchdog only after anything that is expected to be time
- // consuming has completed, otherwise the process is liable to be aborted.
- if (enable_watchdog) {
- watchdog_thread_ = new GpuWatchdogThread(kGpuTimeout);
- watchdog_thread_->Start();
- }
-}
-
-void GpuThread::StopWatchdog() {
- if (watchdog_thread_.get()) {
- watchdog_thread_->Stop();
- }
-}
-
void GpuThread::OnEstablishChannel(int renderer_id) {
scoped_refptr<GpuChannel> channel;
IPC::ChannelHandle channel_handle;
diff --git a/chrome/gpu/gpu_thread.h b/chrome/gpu/gpu_thread.h
index 1d0f434..07302d3 100644
--- a/chrome/gpu/gpu_thread.h
+++ b/chrome/gpu/gpu_thread.h
@@ -7,7 +7,6 @@
#pragma once
#include "base/basictypes.h"
-#include "base/command_line.h"
#include "base/scoped_ptr.h"
#include "base/time.h"
#include "build/build_config.h"
@@ -22,15 +21,12 @@ namespace IPC {
struct ChannelHandle;
}
-class GpuWatchdogThread;
-
class GpuThread : public ChildThread {
public:
- explicit GpuThread(const CommandLine& command_line);
+ GpuThread();
~GpuThread();
void Init(const base::Time& process_start_time);
- void StopWatchdog();
// Remove the channel for a particular renderer.
void RemoveChannel(int renderer_id);
@@ -40,7 +36,6 @@ class GpuThread : public ChildThread {
virtual bool OnControlMessageReceived(const IPC::Message& msg);
// Message handlers.
- void OnInitialize();
void OnEstablishChannel(int renderer_id);
void OnCloseChannel(const IPC::ChannelHandle& channel_handle);
void OnSynchronize();
@@ -58,10 +53,6 @@ class GpuThread : public ChildThread {
static void SetDxDiagnostics(GpuThread* thread, const DxDiagNode& node);
#endif
- CommandLine command_line_;
- base::Time process_start_time_;
- scoped_refptr<GpuWatchdogThread> watchdog_thread_;
-
typedef base::hash_map<int, scoped_refptr<GpuChannel> > GpuChannelMap;
GpuChannelMap gpu_channels_;