Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/browser_main_posix.h" | 5 #include "chrome/browser/browser_main_posix.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <limits.h> | 8 #include <limits.h> |
| 9 #include <signal.h> | 9 #include <signal.h> |
| 10 #include <sys/resource.h> | 10 #include <sys/resource.h> |
| 11 #include <unistd.h> | 11 #include <unistd.h> |
| 12 | 12 |
| 13 #include <string> | 13 #include <string> |
| 14 | 14 |
| 15 #include "base/command_line.h" | 15 #include "base/command_line.h" |
| 16 #include "base/eintr_wrapper.h" | 16 #include "base/eintr_wrapper.h" |
| 17 #include "base/logging.h" | 17 #include "base/logging.h" |
| 18 #include "base/string_number_conversions.h" | 18 #include "base/string_number_conversions.h" |
| 19 #include "chrome/browser/defaults.h" | 19 #include "chrome/browser/defaults.h" |
| 20 #include "chrome/browser/ui/browser_list.h" | 20 #include "chrome/browser/ui/browser_list.h" |
| 21 #include "chrome/common/chrome_switches.h" | 21 #include "chrome/common/chrome_switches.h" |
| 22 #include "content/browser/browser_thread.h" | 22 #include "content/browser/browser_thread.h" |
| 23 | 23 |
| 24 #if defined(TOOLKIT_USES_GTK) && !defined(OS_CHROMEOS) | 24 #if defined(TOOLKIT_USES_GTK) && !defined(OS_CHROMEOS) |
| 25 #include "chrome/browser/printing/print_dialog_gtk.h" | 25 #include "chrome/browser/printing/print_dialog_gtk.h" |
| 26 #endif | 26 #endif |
| 27 | 27 |
| 28 namespace { | 28 namespace { |
| 29 | 29 |
| 30 // See comment in |PreEarlyInitialization()|, where sigaction is called. | 30 // See comment in |PreEarlyInitialization()|, where sigaction is called. |
|
viettrungluu
2011/07/21 18:00:20
Update this comment.
oshima
2011/07/22 01:36:30
SIGCHLDHandler was moved back to PreEarlyInitializ
| |
| 31 void SIGCHLDHandler(int signal) { | 31 void SIGCHLDHandler(int signal) { |
| 32 } | 32 } |
| 33 | 33 |
| 34 int g_shutdown_pipe_write_fd = -1; | 34 int g_shutdown_pipe_write_fd = -1; |
| 35 int g_shutdown_pipe_read_fd = -1; | 35 int g_shutdown_pipe_read_fd = -1; |
| 36 | 36 |
| 37 // Common code between SIG{HUP, INT, TERM}Handler. | 37 // Common code between SIG{HUP, INT, TERM}Handler. |
| 38 void GracefulShutdownHandler(int signal) { | 38 void GracefulShutdownHandler(int signal) { |
| 39 // Reinstall the default handler. We had one shot at graceful shutdown. | 39 // Reinstall the default handler. We had one shot at graceful shutdown. |
| 40 struct sigaction action; | 40 struct sigaction action; |
| 41 memset(&action, 0, sizeof(action)); | 41 memset(&action, 0, sizeof(action)); |
| 42 action.sa_handler = SIG_DFL; | 42 action.sa_handler = SIG_DFL; |
| 43 RAW_CHECK(sigaction(signal, &action, NULL) == 0); | 43 RAW_CHECK(sigaction(signal, &action, NULL) == 0); |
| 44 | 44 |
| 45 RAW_CHECK(g_shutdown_pipe_write_fd != -1); | 45 RAW_CHECK(g_shutdown_pipe_write_fd != -1); |
| 46 RAW_CHECK(g_shutdown_pipe_read_fd != -1); | 46 RAW_CHECK(g_shutdown_pipe_read_fd != -1); |
| 47 size_t bytes_written = 0; | 47 size_t bytes_written = 0; |
| 48 do { | 48 do { |
| 49 int rv = HANDLE_EINTR( | 49 int rv = HANDLE_EINTR( |
| 50 write(g_shutdown_pipe_write_fd, | 50 write(g_shutdown_pipe_write_fd, |
| 51 reinterpret_cast<const char*>(&signal) + bytes_written, | 51 reinterpret_cast<const char*>(&signal) + bytes_written, |
| 52 sizeof(signal) - bytes_written)); | 52 sizeof(signal) - bytes_written)); |
| 53 RAW_CHECK(rv >= 0); | 53 RAW_CHECK(rv >= 0); |
| 54 bytes_written += rv; | 54 bytes_written += rv; |
| 55 } while (bytes_written < sizeof(signal)); | 55 } while (bytes_written < sizeof(signal)); |
| 56 } | 56 } |
| 57 | 57 |
| 58 // See comment in |PreEarlyInitialization()|, where sigaction is called. | 58 // See comment in |PreEarlyInitialization()|, where sigaction is called. |
|
viettrungluu
2011/07/21 18:00:20
Ditto, etc.
oshima
2011/07/22 01:36:30
Done.
| |
| 59 void SIGHUPHandler(int signal) { | 59 void SIGHUPHandler(int signal) { |
| 60 RAW_CHECK(signal == SIGHUP); | 60 RAW_CHECK(signal == SIGHUP); |
| 61 GracefulShutdownHandler(signal); | 61 GracefulShutdownHandler(signal); |
| 62 } | 62 } |
| 63 | 63 |
| 64 // See comment in |PreEarlyInitialization()|, where sigaction is called. | 64 // See comment in |PreEarlyInitialization()|, where sigaction is called. |
| 65 void SIGINTHandler(int signal) { | 65 void SIGINTHandler(int signal) { |
| 66 RAW_CHECK(signal == SIGINT); | 66 RAW_CHECK(signal == SIGINT); |
| 67 GracefulShutdownHandler(signal); | 67 GracefulShutdownHandler(signal); |
| 68 } | 68 } |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 180 } else { | 180 } else { |
| 181 PLOG(INFO) << "Failed to get file descriptor limit"; | 181 PLOG(INFO) << "Failed to get file descriptor limit"; |
| 182 } | 182 } |
| 183 } | 183 } |
| 184 | 184 |
| 185 } // namespace | 185 } // namespace |
| 186 | 186 |
| 187 // BrowserMainPartsPosix ------------------------------------------------------- | 187 // BrowserMainPartsPosix ------------------------------------------------------- |
| 188 | 188 |
| 189 void BrowserMainPartsPosix::PreEarlyInitialization() { | 189 void BrowserMainPartsPosix::PreEarlyInitialization() { |
| 190 // We need to accept SIGCHLD, even though our handler is a no-op because | |
| 191 // otherwise we cannot wait on children. (According to POSIX 2001.) | |
| 192 struct sigaction action; | |
| 193 memset(&action, 0, sizeof(action)); | |
| 194 action.sa_handler = SIGCHLDHandler; | |
| 195 CHECK(sigaction(SIGCHLD, &action, NULL) == 0); | |
| 196 | |
| 197 // If adding to this list of signal handlers, note the new signal probably | |
| 198 // needs to be reset in child processes. See | |
| 199 // base/process_util_posix.cc:LaunchProcess. | |
| 200 | |
| 201 // We need to handle SIGTERM, because that is how many POSIX-based distros ask | |
| 202 // processes to quit gracefully at shutdown time. | |
| 203 memset(&action, 0, sizeof(action)); | |
| 204 action.sa_handler = SIGTERMHandler; | |
| 205 CHECK(sigaction(SIGTERM, &action, NULL) == 0); | |
| 206 // Also handle SIGINT - when the user terminates the browser via Ctrl+C. If | |
| 207 // the browser process is being debugged, GDB will catch the SIGINT first. | |
| 208 action.sa_handler = SIGINTHandler; | |
| 209 CHECK(sigaction(SIGINT, &action, NULL) == 0); | |
| 210 // And SIGHUP, for when the terminal disappears. On shutdown, many Linux | |
| 211 // distros send SIGHUP, SIGTERM, and then SIGKILL. | |
| 212 action.sa_handler = SIGHUPHandler; | |
| 213 CHECK(sigaction(SIGHUP, &action, NULL) == 0); | |
| 214 | |
| 215 const std::string fd_limit_string = | 190 const std::string fd_limit_string = |
| 216 parsed_command_line().GetSwitchValueASCII( | 191 parsed_command_line().GetSwitchValueASCII( |
| 217 switches::kFileDescriptorLimit); | 192 switches::kFileDescriptorLimit); |
| 218 int fd_limit = 0; | 193 int fd_limit = 0; |
| 219 if (!fd_limit_string.empty()) { | 194 if (!fd_limit_string.empty()) { |
| 220 base::StringToInt(fd_limit_string, &fd_limit); | 195 base::StringToInt(fd_limit_string, &fd_limit); |
| 221 } | 196 } |
| 222 #if defined(OS_MACOSX) | 197 #if defined(OS_MACOSX) |
| 223 // We use quite a few file descriptors for our IPC, and the default limit on | 198 // We use quite a few file descriptors for our IPC, and the default limit on |
| 224 // the Mac is low (256), so bump it up if there is no explicit override. | 199 // the Mac is low (256), so bump it up if there is no explicit override. |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 250 g_shutdown_pipe_write_fd = pipefd[1]; | 225 g_shutdown_pipe_write_fd = pipefd[1]; |
| 251 const size_t kShutdownDetectorThreadStackSize = 4096; | 226 const size_t kShutdownDetectorThreadStackSize = 4096; |
| 252 // TODO(viettrungluu,willchan): crbug.com/29675 - This currently leaks, so | 227 // TODO(viettrungluu,willchan): crbug.com/29675 - This currently leaks, so |
| 253 // if you change this, you'll probably need to change the suppression. | 228 // if you change this, you'll probably need to change the suppression. |
| 254 if (!base::PlatformThread::CreateNonJoinable( | 229 if (!base::PlatformThread::CreateNonJoinable( |
| 255 kShutdownDetectorThreadStackSize, | 230 kShutdownDetectorThreadStackSize, |
| 256 new ShutdownDetector(g_shutdown_pipe_read_fd))) { | 231 new ShutdownDetector(g_shutdown_pipe_read_fd))) { |
| 257 LOG(DFATAL) << "Failed to create shutdown detector task."; | 232 LOG(DFATAL) << "Failed to create shutdown detector task."; |
| 258 } | 233 } |
| 259 } | 234 } |
| 235 // Setup signal handlers AFTER shutodwn pipe is setup because | |
|
viettrungluu
2011/07/21 18:00:20
s/shutodwn/shutdown/
| |
| 236 // it may be called right away after handler is set. | |
| 237 | |
| 238 // We need to accept SIGCHLD, even though our handler is a no-op because | |
|
viettrungluu
2011/07/21 18:00:20
We can presumably set up the SIGCHLD handler earli
oshima
2011/07/22 01:36:30
You're right. I moved SIGCHLDHandler back to PreEa
| |
| 239 // otherwise we cannot wait on children. (According to POSIX 2001.) | |
| 240 struct sigaction action; | |
| 241 memset(&action, 0, sizeof(action)); | |
| 242 action.sa_handler = SIGCHLDHandler; | |
| 243 CHECK(sigaction(SIGCHLD, &action, NULL) == 0); | |
| 244 | |
| 245 // If adding to this list of signal handlers, note the new signal probably | |
| 246 // needs to be reset in child processes. See | |
| 247 // base/process_util_posix.cc:LaunchProcess. | |
| 248 | |
| 249 // We need to handle SIGTERM, because that is how many POSIX-based distros ask | |
| 250 // processes to quit gracefully at shutdown time. | |
| 251 memset(&action, 0, sizeof(action)); | |
| 252 action.sa_handler = SIGTERMHandler; | |
| 253 CHECK(sigaction(SIGTERM, &action, NULL) == 0); | |
| 254 // Also handle SIGINT - when the user terminates the browser via Ctrl+C. If | |
| 255 // the browser process is being debugged, GDB will catch the SIGINT first. | |
| 256 action.sa_handler = SIGINTHandler; | |
| 257 CHECK(sigaction(SIGINT, &action, NULL) == 0); | |
| 258 // And SIGHUP, for when the terminal disappears. On shutdown, many Linux | |
| 259 // distros send SIGHUP, SIGTERM, and then SIGKILL. | |
| 260 action.sa_handler = SIGHUPHandler; | |
| 261 CHECK(sigaction(SIGHUP, &action, NULL) == 0); | |
| 260 | 262 |
| 261 #if defined(TOOLKIT_USES_GTK) && !defined(OS_CHROMEOS) | 263 #if defined(TOOLKIT_USES_GTK) && !defined(OS_CHROMEOS) |
| 262 printing::PrintingContextCairo::SetCreatePrintDialogFunction( | 264 printing::PrintingContextCairo::SetCreatePrintDialogFunction( |
| 263 &PrintDialogGtk::CreatePrintDialog); | 265 &PrintDialogGtk::CreatePrintDialog); |
| 264 #endif | 266 #endif |
| 265 } | 267 } |
| OLD | NEW |