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

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

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