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 "chrome/browser/browser_main_posix.h" |
| 6 |
5 #include <errno.h> | 7 #include <errno.h> |
6 #include <signal.h> | 8 #include <signal.h> |
7 #include <sys/resource.h> | 9 #include <sys/resource.h> |
8 | 10 |
9 #include "base/command_line.h" | 11 #include "base/command_line.h" |
10 #include "base/eintr_wrapper.h" | 12 #include "base/eintr_wrapper.h" |
11 #include "base/logging.h" | 13 #include "base/logging.h" |
12 #include "base/string_util.h" | 14 #include "base/string_util.h" |
13 #include "chrome/browser/browser_list.h" | 15 #include "chrome/browser/browser_list.h" |
14 #include "chrome/browser/browser_main.h" | |
15 #include "chrome/browser/chrome_thread.h" | 16 #include "chrome/browser/chrome_thread.h" |
16 #include "chrome/common/chrome_switches.h" | 17 #include "chrome/common/chrome_switches.h" |
17 | 18 |
18 namespace { | 19 namespace { |
19 | 20 |
20 // See comment in |PreEarlyInitialization()|, where sigaction is called. | 21 // See comment in |PreEarlyInitialization()|, where sigaction is called. |
21 void SIGCHLDHandler(int signal) { | 22 void SIGCHLDHandler(int signal) { |
22 } | 23 } |
23 | 24 |
24 int g_shutdown_pipe_write_fd = -1; | 25 int g_shutdown_pipe_write_fd = -1; |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 } | 149 } |
149 } else { | 150 } else { |
150 PLOG(INFO) << "Failed to get file descriptor limit"; | 151 PLOG(INFO) << "Failed to get file descriptor limit"; |
151 } | 152 } |
152 } | 153 } |
153 | 154 |
154 } // namespace | 155 } // namespace |
155 | 156 |
156 // BrowserMainPartsPosix ------------------------------------------------------- | 157 // BrowserMainPartsPosix ------------------------------------------------------- |
157 | 158 |
158 class BrowserMainPartsPosix : public BrowserMainParts { | 159 void BrowserMainPartsPosix::PreEarlyInitialization() { |
159 public: | 160 // We need to accept SIGCHLD, even though our handler is a no-op because |
160 explicit BrowserMainPartsPosix(const MainFunctionParams& parameters) | 161 // otherwise we cannot wait on children. (According to POSIX 2001.) |
161 : BrowserMainParts(parameters) {} | 162 struct sigaction action; |
| 163 memset(&action, 0, sizeof(action)); |
| 164 action.sa_handler = SIGCHLDHandler; |
| 165 CHECK(sigaction(SIGCHLD, &action, NULL) == 0); |
162 | 166 |
163 virtual void TemporaryPosix_1() { | 167 // If adding to this list of signal handlers, note the new signal probably |
164 int pipefd[2]; | 168 // needs to be reset in child processes. See |
165 int ret = pipe(pipefd); | 169 // base/process_util_posix.cc:LaunchApp |
166 if (ret < 0) { | 170 |
167 PLOG(DFATAL) << "Failed to create pipe"; | 171 // We need to handle SIGTERM, because that is how many POSIX-based distros ask |
168 } else { | 172 // processes to quit gracefully at shutdown time. |
169 g_shutdown_pipe_read_fd = pipefd[0]; | 173 memset(&action, 0, sizeof(action)); |
170 g_shutdown_pipe_write_fd = pipefd[1]; | 174 action.sa_handler = SIGTERMHandler; |
171 const size_t kShutdownDetectorThreadStackSize = 4096; | 175 CHECK(sigaction(SIGTERM, &action, NULL) == 0); |
172 if (!PlatformThread::CreateNonJoinable( | 176 // Also handle SIGINT - when the user terminates the browser via Ctrl+C. If |
173 kShutdownDetectorThreadStackSize, | 177 // the browser process is being debugged, GDB will catch the SIGINT first. |
174 new ShutdownDetector(g_shutdown_pipe_read_fd))) { | 178 action.sa_handler = SIGINTHandler; |
175 LOG(DFATAL) << "Failed to create shutdown detector task."; | 179 CHECK(sigaction(SIGINT, &action, NULL) == 0); |
176 } | 180 // And SIGHUP, for when the terminal disappears. On shutdown, many Linux |
| 181 // distros send SIGHUP, SIGTERM, and then SIGKILL. |
| 182 action.sa_handler = SIGHUPHandler; |
| 183 CHECK(sigaction(SIGHUP, &action, NULL) == 0); |
| 184 |
| 185 const std::string fd_limit_string = |
| 186 parsed_command_line().GetSwitchValueASCII( |
| 187 switches::kFileDescriptorLimit); |
| 188 int fd_limit = 0; |
| 189 if (!fd_limit_string.empty()) { |
| 190 StringToInt(fd_limit_string, &fd_limit); |
| 191 } |
| 192 #if defined(OS_MACOSX) |
| 193 // We use quite a few file descriptors for our IPC, and the default limit on |
| 194 // the Mac is low (256), so bump it up if there is no explicit override. |
| 195 if (fd_limit == 0) { |
| 196 fd_limit = 1024; |
| 197 } |
| 198 #endif // OS_MACOSX |
| 199 if (fd_limit > 0) |
| 200 SetFileDescriptorLimit(fd_limit); |
| 201 } |
| 202 |
| 203 void BrowserMainPartsPosix::PostMainMessageLoopStart() { |
| 204 int pipefd[2]; |
| 205 int ret = pipe(pipefd); |
| 206 if (ret < 0) { |
| 207 PLOG(DFATAL) << "Failed to create pipe"; |
| 208 } else { |
| 209 g_shutdown_pipe_read_fd = pipefd[0]; |
| 210 g_shutdown_pipe_write_fd = pipefd[1]; |
| 211 const size_t kShutdownDetectorThreadStackSize = 4096; |
| 212 if (!PlatformThread::CreateNonJoinable( |
| 213 kShutdownDetectorThreadStackSize, |
| 214 new ShutdownDetector(g_shutdown_pipe_read_fd))) { |
| 215 LOG(DFATAL) << "Failed to create shutdown detector task."; |
177 } | 216 } |
178 } | 217 } |
| 218 } |
179 | 219 |
180 private: | 220 // Mac further subclasses BrowserMainPartsPosix |
181 virtual void PreEarlyInitialization() { | 221 #if !defined(OS_MACOSX) |
182 // We need to accept SIGCHLD, even though our handler is a no-op because | |
183 // otherwise we cannot wait on children. (According to POSIX 2001.) | |
184 struct sigaction action; | |
185 memset(&action, 0, sizeof(action)); | |
186 action.sa_handler = SIGCHLDHandler; | |
187 CHECK(sigaction(SIGCHLD, &action, NULL) == 0); | |
188 | |
189 // If adding to this list of signal handlers, note the new signal probably | |
190 // needs to be reset in child processes. See | |
191 // base/process_util_posix.cc:LaunchApp | |
192 | |
193 // We need to handle SIGTERM, because that is how many POSIX-based distros | |
194 // ask processes to quit gracefully at shutdown time. | |
195 memset(&action, 0, sizeof(action)); | |
196 action.sa_handler = SIGTERMHandler; | |
197 CHECK(sigaction(SIGTERM, &action, NULL) == 0); | |
198 // Also handle SIGINT - when the user terminates the browser via Ctrl+C. If | |
199 // the browser process is being debugged, GDB will catch the SIGINT first. | |
200 action.sa_handler = SIGINTHandler; | |
201 CHECK(sigaction(SIGINT, &action, NULL) == 0); | |
202 // And SIGHUP, for when the terminal disappears. On shutdown, many Linux | |
203 // distros send SIGHUP, SIGTERM, and then SIGKILL. | |
204 action.sa_handler = SIGHUPHandler; | |
205 CHECK(sigaction(SIGHUP, &action, NULL) == 0); | |
206 | |
207 const std::string fd_limit_string = | |
208 parsed_command_line().GetSwitchValueASCII( | |
209 switches::kFileDescriptorLimit); | |
210 int fd_limit = 0; | |
211 if (!fd_limit_string.empty()) { | |
212 StringToInt(fd_limit_string, &fd_limit); | |
213 } | |
214 #if defined(OS_MACOSX) | |
215 // We use quite a few file descriptors for our IPC, and the default limit on | |
216 // the Mac is low (256), so bump it up if there is no explicit override. | |
217 if (fd_limit == 0) { | |
218 fd_limit = 1024; | |
219 } | |
220 #endif // OS_MACOSX | |
221 if (fd_limit > 0) | |
222 SetFileDescriptorLimit(fd_limit); | |
223 } | |
224 }; | |
225 | |
226 // static | 222 // static |
227 BrowserMainParts* BrowserMainParts::CreateBrowserMainParts( | 223 BrowserMainParts* BrowserMainParts::CreateBrowserMainParts( |
228 const MainFunctionParams& parameters) { | 224 const MainFunctionParams& parameters) { |
229 return new BrowserMainPartsPosix(parameters); | 225 return new BrowserMainPartsPosix(parameters); |
230 } | 226 } |
| 227 #endif // !defined(OS_MACOSX) |
OLD | NEW |