| OLD | NEW |
| 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 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 views::AcceleratorHandler accelerator_handler; | 148 views::AcceleratorHandler accelerator_handler; |
| 149 MessageLoopForUI::current()->Run(&accelerator_handler); | 149 MessageLoopForUI::current()->Run(&accelerator_handler); |
| 150 #elif defined(OS_LINUX) | 150 #elif defined(OS_LINUX) |
| 151 MessageLoopForUI::current()->Run(NULL); | 151 MessageLoopForUI::current()->Run(NULL); |
| 152 #elif defined(OS_POSIX) | 152 #elif defined(OS_POSIX) |
| 153 MessageLoopForUI::current()->Run(); | 153 MessageLoopForUI::current()->Run(); |
| 154 #endif | 154 #endif |
| 155 } | 155 } |
| 156 | 156 |
| 157 #if defined(OS_POSIX) | 157 #if defined(OS_POSIX) |
| 158 // See comment below, where sigaction is called. | 158 // See comment in BrowserMain, where sigaction is called. |
| 159 void SIGCHLDHandler(int signal) { | 159 void SIGCHLDHandler(int signal) { |
| 160 } | 160 } |
| 161 | 161 |
| 162 // See comment below, where sigaction is called. | 162 // See comment in BrowserMain, where sigaction is called. |
| 163 void SIGTERMHandler(int signal) { | 163 void SIGTERMHandler(int signal) { |
| 164 DCHECK_EQ(signal, SIGTERM); | 164 DCHECK_EQ(signal, SIGTERM); |
| 165 LOG(WARNING) << "Addressing SIGTERM on " << PlatformThread::CurrentId(); | 165 LOG(WARNING) << "Addressing SIGTERM on " << PlatformThread::CurrentId(); |
| 166 |
| 166 MessageLoop* main_loop = ChromeThread::GetMessageLoop(ChromeThread::UI); | 167 MessageLoop* main_loop = ChromeThread::GetMessageLoop(ChromeThread::UI); |
| 167 if (main_loop) { | 168 if (main_loop) { |
| 168 main_loop->PostTask(FROM_HERE, | 169 // Post the exit task to the main thread. |
| 169 NewRunnableFunction( | 170 main_loop->PostTask( |
| 170 BrowserList::CloseAllBrowsers, true)); | 171 FROM_HERE, NewRunnableFunction(BrowserList::CloseAllBrowsersAndExit)); |
| 172 LOG(WARNING) << "Posted task to UI thread; resetting SIGTERM handler"; |
| 171 } | 173 } |
| 174 |
| 172 // Reinstall the default handler. We had one shot at graceful shutdown. | 175 // Reinstall the default handler. We had one shot at graceful shutdown. |
| 173 LOG(WARNING) << "Posted task to UI thread; resetting SIGTERM handler."; | |
| 174 struct sigaction term_action; | 176 struct sigaction term_action; |
| 175 memset(&term_action, 0, sizeof(term_action)); | 177 memset(&term_action, 0, sizeof(term_action)); |
| 176 term_action.sa_handler = SIG_DFL; | 178 term_action.sa_handler = SIG_DFL; |
| 177 CHECK(sigaction(SIGTERM, &term_action, NULL) == 0); | 179 CHECK(sigaction(SIGTERM, &term_action, NULL) == 0); |
| 180 |
| 181 if (!main_loop) { |
| 182 // Without a UI thread to post the exit task to, there aren't many |
| 183 // options. Raise the signal again. The default handler will pick it up |
| 184 // and cause an ungraceful exit. |
| 185 LOG(WARNING) << "No UI thread, exiting ungracefully"; |
| 186 kill(getpid(), signal); |
| 187 |
| 188 // The signal may be handled on another thread. Give that a chance to |
| 189 // happen. |
| 190 sleep(3); |
| 191 |
| 192 // We really should be dead by now. For whatever reason, we're not. Exit |
| 193 // immediately, with the exit status set to the signal number with bit 8 |
| 194 // set. On the systems that we care about, this exit status is what is |
| 195 // normally used to indicate an exit by this signal's default handler. |
| 196 // This mechanism isn't a de jure standard, but even in the worst case, it |
| 197 // should at least result in an immediate exit. |
| 198 LOG(WARNING) << "Still here, exiting really ungracefully"; |
| 199 _exit(signal | (1 << 7)); |
| 200 } |
| 178 } | 201 } |
| 179 | 202 |
| 180 // Sets the file descriptor soft limit to |max_descriptors| or the OS hard | 203 // Sets the file descriptor soft limit to |max_descriptors| or the OS hard |
| 181 // limit, whichever is lower. | 204 // limit, whichever is lower. |
| 182 void SetFileDescriptorLimit(unsigned int max_descriptors) { | 205 void SetFileDescriptorLimit(unsigned int max_descriptors) { |
| 183 struct rlimit limits; | 206 struct rlimit limits; |
| 184 if (getrlimit(RLIMIT_NOFILE, &limits) == 0) { | 207 if (getrlimit(RLIMIT_NOFILE, &limits) == 0) { |
| 185 unsigned int new_limit = max_descriptors; | 208 unsigned int new_limit = max_descriptors; |
| 186 if (limits.rlim_max > 0 && limits.rlim_max < max_descriptors) { | 209 if (limits.rlim_max > 0 && limits.rlim_max < max_descriptors) { |
| 187 new_limit = limits.rlim_max; | 210 new_limit = limits.rlim_max; |
| (...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 866 if (metrics) | 889 if (metrics) |
| 867 metrics->Stop(); | 890 metrics->Stop(); |
| 868 | 891 |
| 869 // browser_shutdown takes care of deleting browser_process, so we need to | 892 // browser_shutdown takes care of deleting browser_process, so we need to |
| 870 // release it. | 893 // release it. |
| 871 browser_process.release(); | 894 browser_process.release(); |
| 872 browser_shutdown::Shutdown(); | 895 browser_shutdown::Shutdown(); |
| 873 | 896 |
| 874 return result_code; | 897 return result_code; |
| 875 } | 898 } |
| OLD | NEW |