diff options
author | mark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-12 04:32:14 +0000 |
---|---|---|
committer | mark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-12 04:32:14 +0000 |
commit | a93244407e205a8619d620ce91bafbdf88eab195 (patch) | |
tree | 11cb0d23c6936c0e867c15aacd8450f4bb40cce2 /chrome/browser | |
parent | 4dee39c5d979e25a0515e3f97d3657a464dd7d79 (diff) | |
download | chromium_src-a93244407e205a8619d620ce91bafbdf88eab195.zip chromium_src-a93244407e205a8619d620ce91bafbdf88eab195.tar.gz chromium_src-a93244407e205a8619d620ce91bafbdf88eab195.tar.bz2 |
SIGTERM should cause the application to exit on the Mac.
BUG=23551
TEST=Send SIGTERM to the browser process. It should exit cleanly.
Review URL: http://codereview.chromium.org/269048
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@28695 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/automation/automation_provider.cc | 2 | ||||
-rw-r--r-- | chrome/browser/browser.cc | 2 | ||||
-rw-r--r-- | chrome/browser/browser_list.cc | 17 | ||||
-rw-r--r-- | chrome/browser/browser_list.h | 6 | ||||
-rw-r--r-- | chrome/browser/browser_main.cc | 35 | ||||
-rw-r--r-- | chrome/browser/chrome_application_mac.h | 13 | ||||
-rw-r--r-- | chrome/browser/chrome_application_mac.mm | 8 |
7 files changed, 75 insertions, 8 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc index 89a8ec9..e0b6b1a 100644 --- a/chrome/browser/automation/automation_provider.cc +++ b/chrome/browser/automation/automation_provider.cc @@ -1699,7 +1699,7 @@ TestingAutomationProvider::~TestingAutomationProvider() { } void TestingAutomationProvider::OnChannelError() { - BrowserList::CloseAllBrowsers(true); + BrowserList::CloseAllBrowsersAndExit(); AutomationProvider::OnChannelError(); } diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index ab32402..78191f7 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -891,7 +891,7 @@ void Browser::ToggleFullscreenMode() { void Browser::Exit() { UserMetrics::RecordAction(L"Exit", profile_); - BrowserList::CloseAllBrowsers(true); + BrowserList::CloseAllBrowsersAndExit(); } void Browser::BookmarkCurrentPage() { diff --git a/chrome/browser/browser_list.cc b/chrome/browser/browser_list.cc index 24b796c..8db7b46 100644 --- a/chrome/browser/browser_list.cc +++ b/chrome/browser/browser_list.cc @@ -17,6 +17,10 @@ #include "chrome/common/notification_service.h" #include "chrome/common/result_codes.h" +#if defined(OS_MACOSX) +#include "chrome/browser/chrome_application_mac.h" +#endif + namespace { // This object is instantiated when the first Browser object is added to the @@ -186,6 +190,19 @@ void BrowserList::CloseAllBrowsers(bool use_post) { } // static +void BrowserList::CloseAllBrowsersAndExit() { +#if !defined(OS_MACOSX) + // On most platforms, closing all windows causes the application to exit. + CloseAllBrowsers(true); +#else + // On the Mac, the application continues to run once all windows are closed. + // Terminate will result in a CloseAllBrowsers(true) call, and additionally, + // will cause the application to exit cleanly. + CrApplicationCC::Terminate(); +#endif +} + +// static void BrowserList::WindowsSessionEnding() { // EndSession is invoked once per frame. Only do something the first time. static bool already_ended = false; diff --git a/chrome/browser/browser_list.h b/chrome/browser/browser_list.h index de07b9a..b510b8c 100644 --- a/chrome/browser/browser_list.h +++ b/chrome/browser/browser_list.h @@ -78,6 +78,12 @@ class BrowserList { // the session. use_post should only be false when invoked from end session. static void CloseAllBrowsers(bool use_post); + // Closes all browsers and exits. This is equivalent to + // CloseAllBrowsers(true) on platforms where the application exits when no + // more windows are remaining. On other platforms (the Mac), this will + // additionally exit the application. + static void CloseAllBrowsersAndExit(); + // Begins shutdown of the application when the Windows session is ending. static void WindowsSessionEnding(); diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc index 2bb6981..9dd411f 100644 --- a/chrome/browser/browser_main.cc +++ b/chrome/browser/browser_main.cc @@ -155,26 +155,49 @@ void RunUIMessageLoop(BrowserProcess* browser_process) { } #if defined(OS_POSIX) -// See comment below, where sigaction is called. +// See comment in BrowserMain, where sigaction is called. void SIGCHLDHandler(int signal) { } -// See comment below, where sigaction is called. +// See comment in BrowserMain, where sigaction is called. void SIGTERMHandler(int signal) { DCHECK_EQ(signal, SIGTERM); LOG(WARNING) << "Addressing SIGTERM on " << PlatformThread::CurrentId(); + MessageLoop* main_loop = ChromeThread::GetMessageLoop(ChromeThread::UI); if (main_loop) { - main_loop->PostTask(FROM_HERE, - NewRunnableFunction( - BrowserList::CloseAllBrowsers, true)); + // Post the exit task to the main thread. + main_loop->PostTask( + FROM_HERE, NewRunnableFunction(BrowserList::CloseAllBrowsersAndExit)); + LOG(WARNING) << "Posted task to UI thread; resetting SIGTERM handler"; } + // Reinstall the default handler. We had one shot at graceful shutdown. - LOG(WARNING) << "Posted task to UI thread; resetting SIGTERM handler."; struct sigaction term_action; memset(&term_action, 0, sizeof(term_action)); term_action.sa_handler = SIG_DFL; CHECK(sigaction(SIGTERM, &term_action, NULL) == 0); + + if (!main_loop) { + // Without a UI thread to post the exit task to, there aren't many + // options. Raise the signal again. The default handler will pick it up + // and cause an ungraceful exit. + LOG(WARNING) << "No UI thread, exiting ungracefully"; + kill(getpid(), signal); + + // The signal may be handled on another thread. Give that a chance to + // happen. + sleep(3); + + // We really should be dead by now. For whatever reason, we're not. Exit + // immediately, with the exit status set to the signal number with bit 8 + // set. On the systems that we care about, this exit status is what is + // normally used to indicate an exit by this signal's default handler. + // This mechanism isn't a de jure standard, but even in the worst case, it + // should at least result in an immediate exit. + LOG(WARNING) << "Still here, exiting really ungracefully"; + _exit(signal | (1 << 7)); + } } // Sets the file descriptor soft limit to |max_descriptors| or the OS hard diff --git a/chrome/browser/chrome_application_mac.h b/chrome/browser/chrome_application_mac.h index b09af38..6d5d95f 100644 --- a/chrome/browser/chrome_application_mac.h +++ b/chrome/browser/chrome_application_mac.h @@ -5,9 +5,22 @@ #ifndef CHROME_BROWSER_CHROME_APPLICATION_MAC_H_ #define CHROME_BROWSER_CHROME_APPLICATION_MAC_H_ +#ifdef __OBJC__ + #import <AppKit/AppKit.h> @interface CrApplication : NSApplication @end +#endif // __OBJC__ + +// CrApplicationCC provides access to CrApplication Objective-C selectors from +// C++ code. +namespace CrApplicationCC { + +// Calls -[NSApp terminate:]. +void Terminate(); + +} // namespace CrApplicationCC + #endif // CHROME_BROWSER_CHROME_APPLICATION_MAC_H_ diff --git a/chrome/browser/chrome_application_mac.mm b/chrome/browser/chrome_application_mac.mm index a94d3aa..a81326f 100644 --- a/chrome/browser/chrome_application_mac.mm +++ b/chrome/browser/chrome_application_mac.mm @@ -84,3 +84,11 @@ } @end + +namespace CrApplicationCC { + +void Terminate() { + [NSApp terminate:nil]; +} + +} // namespace CrApplicationCC |