summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authormark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-12 04:32:14 +0000
committermark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-12 04:32:14 +0000
commita93244407e205a8619d620ce91bafbdf88eab195 (patch)
tree11cb0d23c6936c0e867c15aacd8450f4bb40cce2 /chrome/browser
parent4dee39c5d979e25a0515e3f97d3657a464dd7d79 (diff)
downloadchromium_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.cc2
-rw-r--r--chrome/browser/browser.cc2
-rw-r--r--chrome/browser/browser_list.cc17
-rw-r--r--chrome/browser/browser_list.h6
-rw-r--r--chrome/browser/browser_main.cc35
-rw-r--r--chrome/browser/chrome_application_mac.h13
-rw-r--r--chrome/browser/chrome_application_mac.mm8
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