Index: chrome/browser/ui/browser_list.cc |
diff --git a/chrome/browser/ui/browser_list.cc b/chrome/browser/ui/browser_list.cc |
index 416784d790cbfed2ef7be1b44659e3678253c55d..96995569fe64c395bda9f88bd9dbc1743ab66530 100644 |
--- a/chrome/browser/ui/browser_list.cc |
+++ b/chrome/browser/ui/browser_list.cc |
@@ -202,15 +202,28 @@ bool AreAllBrowsersCloseable() { |
return true; |
} |
+// Emits APP_TERMINATING notification. It is guaranteed that the |
+// notification is sent only once. |
+void NotifyAppTerminating() { |
+ static bool notified = false; |
+ if (notified) |
+ return; |
+ notified = true; |
+ content::NotificationService::current()->Notify( |
+ content::NOTIFICATION_APP_TERMINATING, |
+ content::NotificationService::AllSources(), |
+ content::NotificationService::NoDetails()); |
+} |
+ |
#if defined(OS_CHROMEOS) |
-bool signout = false; |
+// Whether a session manager requested to shutdown. |
+bool g_session_manager_requested_shutdown = true; |
// Fast shutdown for ChromeOS. It tells session manager to start |
// shutdown process when closing browser windows won't be canceled. |
// Returns true if fast shutdown is successfully started. |
bool FastShutdown() { |
- signout = true; |
if (chromeos::CrosLibrary::Get()->EnsureLoaded() |
&& AreAllBrowsersCloseable()) { |
BrowserList::NotifyAndTerminate(true); |
@@ -288,16 +301,17 @@ void BrowserList::AttemptExitInternal() { |
// static |
void BrowserList::NotifyAndTerminate(bool fast_path) { |
#if defined(OS_CHROMEOS) |
- if (!signout) |
+ static bool notified = false; |
+ // Don't ask SessionManager to shutdown if |
+ // a) a shutdown request has already been sent. |
+ // b) shutdown request comes from session manager. |
+ if (notified || g_session_manager_requested_shutdown) |
return; |
+ notified = true; |
#endif |
- if (fast_path) { |
- content::NotificationService::current()->Notify( |
- content::NOTIFICATION_APP_TERMINATING, |
- content::NotificationService::AllSources(), |
- content::NotificationService::NoDetails()); |
- } |
+ if (fast_path) |
+ NotifyAppTerminating(); |
#if defined(OS_CHROMEOS) |
NotifyWindowManagerAboutSignout(); |
@@ -360,10 +374,7 @@ void BrowserList::RemoveBrowser(Browser* browser) { |
// to call ProfileManager::ShutdownSessionServices() as part of the |
// shutdown, because Browser::WindowClosing() already makes sure that the |
// SessionService is created and notified. |
- content::NotificationService::current()->Notify( |
- content::NOTIFICATION_APP_TERMINATING, |
- content::NotificationService::AllSources(), |
- content::NotificationService::NoDetails()); |
+ NotifyAppTerminating(); |
AllBrowsersClosedAndAppExiting(); |
} |
} |
@@ -382,11 +393,6 @@ void BrowserList::RemoveObserver(BrowserList::Observer* observer) { |
void BrowserList::CloseAllBrowsers() { |
bool session_ending = |
browser_shutdown::GetShutdownType() == browser_shutdown::END_SESSION; |
- bool force_exit = false; |
-#if defined(USE_X11) |
- if (session_ending) |
- force_exit = true; |
-#endif |
// Tell everyone that we are shutting down. |
browser_shutdown::SetTryingToQuit(true); |
@@ -396,10 +402,12 @@ void BrowserList::CloseAllBrowsers() { |
// If there are no browsers, send the APP_TERMINATING action here. Otherwise, |
// it will be sent by RemoveBrowser() when the last browser has closed. |
- if (force_exit || browsers_.empty()) { |
+ if (browser_shutdown::ShuttingDownWithoutClosingBrowsers() || |
+ browsers_.empty()) { |
NotifyAndTerminate(true); |
return; |
} |
+ |
#if defined(OS_CHROMEOS) |
chromeos::BootTimesLoader::Get()->AddLogoutTimeMarker( |
"StartedClosingWindows", false); |
@@ -467,6 +475,7 @@ void BrowserList::AttemptUserExit() { |
state->SavePersistentPrefs(); |
} |
} |
+ g_session_manager_requested_shutdown = false; |
if (FastShutdown()) |
return; |
#else |
@@ -505,10 +514,18 @@ void BrowserList::AttemptExit() { |
} |
#if defined(OS_CHROMEOS) |
+// A function called when SIGTERM is received. |
// static |
void BrowserList::ExitCleanly() { |
- // We always mark exit cleanly. |
+ // We always mark exit cleanly because SessionManager may kill |
+ // chrome in 3 seconds after SIGTERM. |
g_browser_process->EndSession(); |
+ |
+ // Don't block when SIGTERM is received. AreaAllBrowsersCloseable() |
+ // can be false in following cases. a) power-off b) signout from |
+ // screen locker. |
+ if (!AreAllBrowsersCloseable()) |
+ browser_shutdown::OnShutdownStarting(browser_shutdown::END_SESSION); |
AttemptExitInternal(); |
} |
#endif |