| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdlib.h> | 5 #include <stdlib.h> |
| 6 | 6 |
| 7 #include "app/app_switches.h" | |
| 8 #include "app/gfx/gl/gl_context.h" | |
| 9 #include "app/gfx/gl/gl_implementation.h" | |
| 10 #include "app/win/scoped_com_initializer.h" | 7 #include "app/win/scoped_com_initializer.h" |
| 11 #include "base/environment.h" | 8 #include "base/environment.h" |
| 12 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 13 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
| 14 #include "base/threading/platform_thread.h" | 11 #include "base/threading/platform_thread.h" |
| 15 #include "build/build_config.h" | 12 #include "build/build_config.h" |
| 16 #include "chrome/common/chrome_constants.h" | 13 #include "chrome/common/chrome_constants.h" |
| 17 #include "chrome/common/chrome_switches.h" | 14 #include "chrome/common/chrome_switches.h" |
| 18 #include "chrome/common/env_vars.h" | 15 #include "chrome/common/env_vars.h" |
| 19 #include "chrome/common/main_function_params.h" | 16 #include "chrome/common/main_function_params.h" |
| 20 #include "chrome/gpu/gpu_config.h" | 17 #include "chrome/gpu/gpu_config.h" |
| 21 #include "chrome/gpu/gpu_process.h" | 18 #include "chrome/gpu/gpu_process.h" |
| 22 #include "chrome/gpu/gpu_thread.h" | 19 #include "chrome/gpu/gpu_thread.h" |
| 23 #include "chrome/gpu/gpu_watchdog_thread.h" | |
| 24 | 20 |
| 25 #if defined(USE_LINUX_BREAKPAD) | 21 #if defined(USE_LINUX_BREAKPAD) |
| 26 #include "chrome/app/breakpad_linux.h" | 22 #include "chrome/app/breakpad_linux.h" |
| 27 #endif | 23 #endif |
| 28 | 24 |
| 29 #if defined(OS_MACOSX) | 25 #if defined(OS_MACOSX) |
| 30 #include "chrome/common/chrome_application_mac.h" | 26 #include "chrome/common/chrome_application_mac.h" |
| 31 #include "chrome/common/sandbox_mac.h" | |
| 32 #endif | 27 #endif |
| 33 | 28 |
| 34 #if defined(USE_X11) | 29 #if defined(USE_X11) |
| 35 #include "gfx/gtk_util.h" | 30 #include "gfx/gtk_util.h" |
| 36 #endif | 31 #endif |
| 37 | 32 |
| 38 const int kGpuTimeout = 10000; | |
| 39 | |
| 40 namespace { | |
| 41 | |
| 42 bool InitializeGpuSandbox() { | |
| 43 #if defined(OS_MACOSX) | |
| 44 CommandLine* parsed_command_line = CommandLine::ForCurrentProcess(); | |
| 45 SandboxInitWrapper sandbox_wrapper; | |
| 46 return sandbox_wrapper.InitializeSandbox(*parsed_command_line, | |
| 47 switches::kGpuProcess); | |
| 48 #else | |
| 49 // TODO(port): Create GPU sandbox for linux and windows. | |
| 50 return true; | |
| 51 #endif | |
| 52 } | |
| 53 | |
| 54 } // namespace | |
| 55 | |
| 56 // Main function for starting the Gpu process. | 33 // Main function for starting the Gpu process. |
| 57 int GpuMain(const MainFunctionParams& parameters) { | 34 int GpuMain(const MainFunctionParams& parameters) { |
| 58 base::Time start_time = base::Time::Now(); | 35 base::Time start_time = base::Time::Now(); |
| 59 | 36 |
| 60 #if defined(USE_LINUX_BREAKPAD) | 37 #if defined(USE_LINUX_BREAKPAD) |
| 61 // Needs to be called after we have chrome::DIR_USER_DATA. | 38 // Needs to be called after we have chrome::DIR_USER_DATA. |
| 62 InitCrashReporter(); | 39 InitCrashReporter(); |
| 63 #endif | 40 #endif |
| 64 | 41 |
| 65 const CommandLine& command_line = parameters.command_line_; | 42 const CommandLine& command_line = parameters.command_line_; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 79 #if defined(USE_X11) | 56 #if defined(USE_X11) |
| 80 // The X11 port of the command buffer code assumes it can access the X | 57 // The X11 port of the command buffer code assumes it can access the X |
| 81 // display via the macro GDK_DISPLAY(), which implies that Gtk has been | 58 // display via the macro GDK_DISPLAY(), which implies that Gtk has been |
| 82 // initialized. This code was taken from PluginThread. TODO(kbr): | 59 // initialized. This code was taken from PluginThread. TODO(kbr): |
| 83 // rethink whether initializing Gtk is really necessary or whether we | 60 // rethink whether initializing Gtk is really necessary or whether we |
| 84 // should just send a raw display connection down to the GPUProcessor. | 61 // should just send a raw display connection down to the GPUProcessor. |
| 85 g_thread_init(NULL); | 62 g_thread_init(NULL); |
| 86 gfx::GtkInitFromCommandLine(command_line); | 63 gfx::GtkInitFromCommandLine(command_line); |
| 87 #endif | 64 #endif |
| 88 | 65 |
| 89 // Note that kNoSandbox will also disable the GPU sandbox. | 66 // We can not tolerate early returns from this code, because the |
| 90 bool no_gpu_sandbox = command_line.HasSwitch(switches::kNoGpuSandbox); | 67 // detection of early return of a child process is implemented using |
| 91 if (!no_gpu_sandbox) { | 68 // an IPC channel error. If the IPC channel is not fully set up |
| 92 if (!InitializeGpuSandbox()) { | 69 // between the browser and GPU process, and the GPU process crashes |
| 93 LOG(ERROR) << "Failed to initialize the GPU sandbox"; | 70 // or exits early, the browser process will never detect it. For |
| 94 return EXIT_FAILURE; | 71 // this reason we defer all work related to the GPU until receiving |
| 95 } | 72 // the GpuMsg_Initialize message from the browser. |
| 96 } else { | |
| 97 LOG(ERROR) << "Running without GPU sandbox"; | |
| 98 } | |
| 99 | |
| 100 // Load the GL implementation and locate the bindings before starting the GPU | |
| 101 // watchdog because this can take a lot of time and the GPU watchdog might | |
| 102 // terminate the GPU process. | |
| 103 if (!gfx::GLContext::InitializeOneOff()) | |
| 104 return EXIT_FAILURE; | |
| 105 | |
| 106 // Do this soon before running the message loop so accurate | |
| 107 // initialization time is recorded in the GPU info. Don't do it before | |
| 108 // starting the watchdog thread since it can take a significant amount of | |
| 109 // time to collect GPU information in GpuThread::Init. | |
| 110 GpuProcess gpu_process; | 73 GpuProcess gpu_process; |
| 111 GpuThread* gpu_thread = new GpuThread; | 74 GpuThread* gpu_thread = new GpuThread(command_line); |
| 112 gpu_thread->Init(start_time); | 75 gpu_thread->Init(start_time); |
| 113 gpu_process.set_main_thread(gpu_thread); | 76 gpu_process.set_main_thread(gpu_thread); |
| 114 | 77 |
| 115 | |
| 116 // In addition to disabling the watchdog if the command line switch is | |
| 117 // present, disable it in two other cases. OSMesa is expected to run very | |
| 118 // slowly. Also disable the watchdog on valgrind because the code is expected | |
| 119 // to run slowly in that case. | |
| 120 bool enable_watchdog = | |
| 121 !command_line.HasSwitch(switches::kDisableGpuWatchdog) && | |
| 122 gfx::GetGLImplementation() != gfx::kGLImplementationOSMesaGL && | |
| 123 !RunningOnValgrind(); | |
| 124 | |
| 125 // Disable the watchdog in debug builds because they tend to only be run by | |
| 126 // developers who will not appreciate the watchdog killing the GPU process. | |
| 127 #ifndef NDEBUG | |
| 128 enable_watchdog = false; | |
| 129 #endif | |
| 130 | |
| 131 // Disable the watchdog for Windows. It tends to abort when the GPU process | |
| 132 // is not hung but still taking a long time to do something. Instead, the | |
| 133 // browser process displays a dialog when it notices that the child window | |
| 134 // is hung giving the user an opportunity to terminate it. This is the | |
| 135 // same mechanism used to abort hung plugins. | |
| 136 #if defined(OS_WIN) | |
| 137 enable_watchdog = false; | |
| 138 #endif | |
| 139 | |
| 140 // Start the GPU watchdog only after anything that is expected to be time | |
| 141 // consuming has completed, otherwise the process is liable to be aborted. | |
| 142 scoped_refptr<GpuWatchdogThread> watchdog_thread; | |
| 143 if (enable_watchdog) { | |
| 144 watchdog_thread = new GpuWatchdogThread(kGpuTimeout); | |
| 145 watchdog_thread->Start(); | |
| 146 } | |
| 147 | |
| 148 main_message_loop.Run(); | 78 main_message_loop.Run(); |
| 149 | 79 |
| 150 if (enable_watchdog) | 80 gpu_thread->StopWatchdog(); |
| 151 watchdog_thread->Stop(); | |
| 152 | 81 |
| 153 return 0; | 82 return 0; |
| 154 } | 83 } |
| OLD | NEW |