Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(508)

Side by Side Diff: chrome/browser/browser_main.cc

Issue 432019: Posix: Catch SIGINT and do a clean shutdown.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: and don't forget sighup Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2009 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.h" 5 #include "chrome/browser/browser_main.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "app/l10n_util.h" 9 #include "app/l10n_util.h"
10 #include "app/resource_bundle.h" 10 #include "app/resource_bundle.h"
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 #elif defined(OS_POSIX) 160 #elif defined(OS_POSIX)
161 MessageLoopForUI::current()->Run(); 161 MessageLoopForUI::current()->Run();
162 #endif 162 #endif
163 } 163 }
164 164
165 #if defined(OS_POSIX) 165 #if defined(OS_POSIX)
166 // See comment in BrowserMain, where sigaction is called. 166 // See comment in BrowserMain, where sigaction is called.
167 void SIGCHLDHandler(int signal) { 167 void SIGCHLDHandler(int signal) {
168 } 168 }
169 169
170 // See comment in BrowserMain, where sigaction is called. 170 // Common code between SIG{HUP, INT, TERM}Handler.
171 void SIGTERMHandler(int signal) { 171 void GracefulShutdownHandler(int signal, const int expected_signal) {
172 DCHECK_EQ(signal, SIGTERM); 172 DCHECK_EQ(signal, expected_signal);
173 LOG(WARNING) << "Addressing SIGTERM on " << PlatformThread::CurrentId(); 173 LOG(WARNING) << "Addressing signal " << expected_signal << " on "
174 << PlatformThread::CurrentId();
174 175
175 bool posted = ChromeThread::PostTask( 176 bool posted = ChromeThread::PostTask(
176 ChromeThread::UI, FROM_HERE, 177 ChromeThread::UI, FROM_HERE,
177 NewRunnableFunction(BrowserList::CloseAllBrowsersAndExit)); 178 NewRunnableFunction(BrowserList::CloseAllBrowsersAndExit));
178 if (posted) {
179 LOG(WARNING) << "Posted task to UI thread; resetting SIGTERM handler";
180 }
181 179
182 // Reinstall the default handler. We had one shot at graceful shutdown. 180 // Reinstall the default handler. We had one shot at graceful shutdown.
183 struct sigaction term_action; 181 struct sigaction term_action;
184 memset(&term_action, 0, sizeof(term_action)); 182 memset(&term_action, 0, sizeof(term_action));
185 term_action.sa_handler = SIG_DFL; 183 term_action.sa_handler = SIG_DFL;
186 CHECK(sigaction(SIGTERM, &term_action, NULL) == 0); 184 CHECK(sigaction(expected_signal, &term_action, NULL) == 0);
187 185
188 if (!posted) { 186 if (posted) {
187 LOG(WARNING) << "Posted task to UI thread; resetting signal "
188 << expected_signal << " handler";
189 } else {
189 // Without a UI thread to post the exit task to, there aren't many 190 // Without a UI thread to post the exit task to, there aren't many
190 // options. Raise the signal again. The default handler will pick it up 191 // options. Raise the signal again. The default handler will pick it up
191 // and cause an ungraceful exit. 192 // and cause an ungraceful exit.
192 LOG(WARNING) << "No UI thread, exiting ungracefully"; 193 LOG(WARNING) << "No UI thread, exiting ungracefully";
193 kill(getpid(), signal); 194 kill(getpid(), signal);
194 195
195 // The signal may be handled on another thread. Give that a chance to 196 // The signal may be handled on another thread. Give that a chance to
196 // happen. 197 // happen.
197 sleep(3); 198 sleep(3);
198 199
199 // We really should be dead by now. For whatever reason, we're not. Exit 200 // We really should be dead by now. For whatever reason, we're not. Exit
200 // immediately, with the exit status set to the signal number with bit 8 201 // immediately, with the exit status set to the signal number with bit 8
201 // set. On the systems that we care about, this exit status is what is 202 // set. On the systems that we care about, this exit status is what is
202 // normally used to indicate an exit by this signal's default handler. 203 // normally used to indicate an exit by this signal's default handler.
203 // This mechanism isn't a de jure standard, but even in the worst case, it 204 // This mechanism isn't a de jure standard, but even in the worst case, it
204 // should at least result in an immediate exit. 205 // should at least result in an immediate exit.
205 LOG(WARNING) << "Still here, exiting really ungracefully"; 206 LOG(WARNING) << "Still here, exiting really ungracefully";
206 _exit(signal | (1 << 7)); 207 _exit(signal | (1 << 7));
207 } 208 }
208 } 209 }
209 210
211 // See comment in BrowserMain, where sigaction is called.
212 void SIGHUPHandler(int signal) {
213 GracefulShutdownHandler(signal, SIGHUP);
214 }
215
216 // See comment in BrowserMain, where sigaction is called.
217 void SIGINTHandler(int signal) {
218 GracefulShutdownHandler(signal, SIGINT);
219 }
220
221 // See comment in BrowserMain, where sigaction is called.
222 void SIGTERMHandler(int signal) {
223 GracefulShutdownHandler(signal, SIGTERM);
224 }
225
210 // Sets the file descriptor soft limit to |max_descriptors| or the OS hard 226 // Sets the file descriptor soft limit to |max_descriptors| or the OS hard
211 // limit, whichever is lower. 227 // limit, whichever is lower.
212 void SetFileDescriptorLimit(unsigned int max_descriptors) { 228 void SetFileDescriptorLimit(unsigned int max_descriptors) {
213 struct rlimit limits; 229 struct rlimit limits;
214 if (getrlimit(RLIMIT_NOFILE, &limits) == 0) { 230 if (getrlimit(RLIMIT_NOFILE, &limits) == 0) {
215 unsigned int new_limit = max_descriptors; 231 unsigned int new_limit = max_descriptors;
216 if (limits.rlim_max > 0 && limits.rlim_max < max_descriptors) { 232 if (limits.rlim_max > 0 && limits.rlim_max < max_descriptors) {
217 new_limit = limits.rlim_max; 233 new_limit = limits.rlim_max;
218 } 234 }
219 limits.rlim_cur = new_limit; 235 limits.rlim_cur = new_limit;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 memset(&action, 0, sizeof(action)); 300 memset(&action, 0, sizeof(action));
285 action.sa_handler = SIGCHLDHandler; 301 action.sa_handler = SIGCHLDHandler;
286 CHECK(sigaction(SIGCHLD, &action, NULL) == 0); 302 CHECK(sigaction(SIGCHLD, &action, NULL) == 0);
287 303
288 // We need to handle SIGTERM, because that is how many POSIX-based distros ask 304 // We need to handle SIGTERM, because that is how many POSIX-based distros ask
289 // processes to quit gracefully at shutdown time. 305 // processes to quit gracefully at shutdown time.
290 struct sigaction term_action; 306 struct sigaction term_action;
291 memset(&term_action, 0, sizeof(term_action)); 307 memset(&term_action, 0, sizeof(term_action));
292 term_action.sa_handler = SIGTERMHandler; 308 term_action.sa_handler = SIGTERMHandler;
293 CHECK(sigaction(SIGTERM, &term_action, NULL) == 0); 309 CHECK(sigaction(SIGTERM, &term_action, NULL) == 0);
310 // Also handle SIGINT - when the user terminates the browser via Ctrl+C.
311 // If the browser process is being debugged, GDB will catch the SIGINT first.
312 CHECK(sigaction(SIGINT, &term_action, NULL) == 0);
313 // And SIGHUP, for when the terminal disappears. On shutdown, many Linux
314 // distros send SIGHUP, SIGTERM, and then SIGKILL.
315 CHECK(sigaction(SIGHUP, &term_action, NULL) == 0);
294 316
295 const std::wstring fd_limit_string = 317 const std::wstring fd_limit_string =
296 parsed_command_line.GetSwitchValue(switches::kFileDescriptorLimit); 318 parsed_command_line.GetSwitchValue(switches::kFileDescriptorLimit);
297 int fd_limit = 0; 319 int fd_limit = 0;
298 if (!fd_limit_string.empty()) { 320 if (!fd_limit_string.empty()) {
299 StringToInt(WideToUTF16Hack(fd_limit_string), &fd_limit); 321 StringToInt(WideToUTF16Hack(fd_limit_string), &fd_limit);
300 } 322 }
301 #if defined(OS_MACOSX) 323 #if defined(OS_MACOSX)
302 // We use quite a few file descriptors for our IPC, and the default limit on 324 // We use quite a few file descriptors for our IPC, and the default limit on
303 // the Mac is low (256), so bump it up if there is no explicit override. 325 // the Mac is low (256), so bump it up if there is no explicit override.
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 if (metrics) 923 if (metrics)
902 metrics->Stop(); 924 metrics->Stop();
903 925
904 // browser_shutdown takes care of deleting browser_process, so we need to 926 // browser_shutdown takes care of deleting browser_process, so we need to
905 // release it. 927 // release it.
906 browser_process.release(); 928 browser_process.release();
907 browser_shutdown::Shutdown(); 929 browser_shutdown::Shutdown();
908 930
909 return result_code; 931 return result_code;
910 } 932 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698