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

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

Issue 517001: Revert 35189 (caused test_shell_tests crashes on valgrind bot):... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 11 years 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 | « build/common.gypi ('k') | 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/hi_res_timer_manager.h" 9 #include "app/hi_res_timer_manager.h"
10 #include "app/l10n_util.h" 10 #include "app/l10n_util.h"
11 #include "app/resource_bundle.h" 11 #include "app/resource_bundle.h"
12 #include "app/system_monitor.h" 12 #include "app/system_monitor.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/field_trial.h" 14 #include "base/field_trial.h"
15 #include "base/file_util.h" 15 #include "base/file_util.h"
16 #include "base/histogram.h" 16 #include "base/histogram.h"
17 #include "base/lazy_instance.h" 17 #include "base/lazy_instance.h"
18 #include "base/scoped_nsautorelease_pool.h" 18 #include "base/scoped_nsautorelease_pool.h"
19 #include "base/path_service.h" 19 #include "base/path_service.h"
20 #include "base/platform_thread.h"
21 #include "base/process_util.h" 20 #include "base/process_util.h"
22 #include "base/string_piece.h" 21 #include "base/string_piece.h"
23 #include "base/string_util.h" 22 #include "base/string_util.h"
24 #include "base/sys_string_conversions.h" 23 #include "base/sys_string_conversions.h"
25 #include "base/time.h" 24 #include "base/time.h"
26 #include "base/tracked_objects.h" 25 #include "base/tracked_objects.h"
27 #include "base/values.h" 26 #include "base/values.h"
28 #include "chrome/browser/browser_main_win.h" 27 #include "chrome/browser/browser_main_win.h"
29 #include "chrome/browser/browser_init.h" 28 #include "chrome/browser/browser_init.h"
30 #include "chrome/browser/browser_list.h" 29 #include "chrome/browser/browser_list.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 #include "net/base/net_module.h" 65 #include "net/base/net_module.h"
67 #include "net/http/http_network_session.h" 66 #include "net/http/http_network_session.h"
68 #include "net/socket/client_socket_pool_base.h" 67 #include "net/socket/client_socket_pool_base.h"
69 68
70 #if defined(OS_POSIX) 69 #if defined(OS_POSIX)
71 // TODO(port): get rid of this include. It's used just to provide declarations 70 // TODO(port): get rid of this include. It's used just to provide declarations
72 // and stub definitions for classes we encouter during the porting effort. 71 // and stub definitions for classes we encouter during the porting effort.
73 #include <errno.h> 72 #include <errno.h>
74 #include <signal.h> 73 #include <signal.h>
75 #include <sys/resource.h> 74 #include <sys/resource.h>
76 #include "base/eintr_wrapper.h"
77 #endif 75 #endif
78 76
79 #if defined(USE_LINUX_BREAKPAD) 77 #if defined(USE_LINUX_BREAKPAD)
80 #include "base/linux_util.h" 78 #include "base/linux_util.h"
81 #include "chrome/app/breakpad_linux.h" 79 #include "chrome/app/breakpad_linux.h"
82 #endif 80 #endif
83 81
84 #if defined(OS_LINUX) 82 #if defined(OS_LINUX)
85 #include "chrome/common/gtk_util.h" 83 #include "chrome/common/gtk_util.h"
86 #endif 84 #endif
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 #elif defined(OS_POSIX) 162 #elif defined(OS_POSIX)
165 MessageLoopForUI::current()->Run(); 163 MessageLoopForUI::current()->Run();
166 #endif 164 #endif
167 } 165 }
168 166
169 #if defined(OS_POSIX) 167 #if defined(OS_POSIX)
170 // See comment in BrowserMain, where sigaction is called. 168 // See comment in BrowserMain, where sigaction is called.
171 void SIGCHLDHandler(int signal) { 169 void SIGCHLDHandler(int signal) {
172 } 170 }
173 171
174 int g_shutdown_pipe_write_fd = -1; 172 // Common code between SIG{HUP, INT, TERM}Handler.
175 int g_shutdown_pipe_read_fd = -1; 173 void GracefulShutdownHandler(int signal, const int expected_signal) {
174 DCHECK_EQ(signal, expected_signal);
175 LOG(INFO) << "Addressing signal " << expected_signal << " on "
176 << PlatformThread::CurrentId();
176 177
177 // Common code between SIG{HUP, INT, TERM}Handler. 178 bool posted = ChromeThread::PostTask(
178 void GracefulShutdownHandler(int signal) { 179 ChromeThread::UI, FROM_HERE,
180 NewRunnableFunction(BrowserList::CloseAllBrowsersAndExit));
181
179 // Reinstall the default handler. We had one shot at graceful shutdown. 182 // Reinstall the default handler. We had one shot at graceful shutdown.
180 struct sigaction action; 183 struct sigaction action;
181 memset(&action, 0, sizeof(action)); 184 memset(&action, 0, sizeof(action));
182 action.sa_handler = SIG_DFL; 185 action.sa_handler = SIG_DFL;
183 CHECK(sigaction(signal, &action, NULL) == 0); 186 CHECK(sigaction(expected_signal, &action, NULL) == 0);
184 187
185 RAW_CHECK(g_shutdown_pipe_write_fd != -1); 188 if (posted) {
186 RAW_CHECK(g_shutdown_pipe_read_fd != -1); 189 LOG(INFO) << "Posted task to UI thread; resetting signal "
187 size_t bytes_written = 0; 190 << expected_signal << " handler";
188 do { 191 } else {
189 int rv = HANDLE_EINTR(
190 write(g_shutdown_pipe_write_fd,
191 reinterpret_cast<const char*>(&signal) + bytes_written,
192 sizeof(signal) - bytes_written));
193 RAW_CHECK(rv >= 0);
194 bytes_written += rv;
195 } while (bytes_written < sizeof(signal));
196
197 RAW_LOG(INFO,
198 "Successfully wrote to shutdown pipe, resetting signal handler.");
199 }
200
201 // See comment in BrowserMain, where sigaction is called.
202 void SIGHUPHandler(int signal) {
203 RAW_CHECK(signal == SIGHUP);
204 RAW_LOG(INFO, "Handling SIGHUP.");
205 GracefulShutdownHandler(signal);
206 }
207
208 // See comment in BrowserMain, where sigaction is called.
209 void SIGINTHandler(int signal) {
210 RAW_CHECK(signal == SIGINT);
211 RAW_LOG(INFO, "Handling SIGINT.");
212 GracefulShutdownHandler(signal);
213 }
214
215 // See comment in BrowserMain, where sigaction is called.
216 void SIGTERMHandler(int signal) {
217 RAW_CHECK(signal == SIGTERM);
218 RAW_LOG(INFO, "Handling SIGTERM.");
219 GracefulShutdownHandler(signal);
220 }
221
222 class ShutdownDetector : public PlatformThread::Delegate {
223 public:
224 explicit ShutdownDetector(int shutdown_fd);
225
226 virtual void ThreadMain();
227
228 private:
229 const int shutdown_fd_;
230
231 DISALLOW_COPY_AND_ASSIGN(ShutdownDetector);
232 };
233
234 ShutdownDetector::ShutdownDetector(int shutdown_fd)
235 : shutdown_fd_(shutdown_fd) {
236 CHECK(shutdown_fd_ != -1);
237 }
238
239 void ShutdownDetector::ThreadMain() {
240 int signal;
241 size_t bytes_read = 0;
242 ssize_t ret;
243 do {
244 ret = HANDLE_EINTR(
245 read(shutdown_fd_,
246 reinterpret_cast<char*>(&signal) + bytes_read,
247 sizeof(signal) - bytes_read));
248 if (ret < 0) {
249 NOTREACHED() << "Unexpected error: " << strerror(errno);
250 break;
251 } else if (ret == 0) {
252 NOTREACHED() << "Unexpected closure of shutdown pipe.";
253 break;
254 }
255 bytes_read += ret;
256 } while (bytes_read < sizeof(signal));
257
258 LOG(INFO) << "Handling shutdown for signal " << signal << ".";
259
260 if (!ChromeThread::PostTask(
261 ChromeThread::UI, FROM_HERE,
262 NewRunnableFunction(BrowserList::CloseAllBrowsersAndExit))) {
263 // Without a UI thread to post the exit task to, there aren't many 192 // Without a UI thread to post the exit task to, there aren't many
264 // options. Raise the signal again. The default handler will pick it up 193 // options. Raise the signal again. The default handler will pick it up
265 // and cause an ungraceful exit. 194 // and cause an ungraceful exit.
266 LOG(WARNING) << "No UI thread, exiting ungracefully."; 195 LOG(WARNING) << "No UI thread, exiting ungracefully";
267 kill(getpid(), signal); 196 kill(getpid(), signal);
268 197
269 // The signal may be handled on another thread. Give that a chance to 198 // The signal may be handled on another thread. Give that a chance to
270 // happen. 199 // happen.
271 sleep(3); 200 sleep(3);
272 201
273 // We really should be dead by now. For whatever reason, we're not. Exit 202 // We really should be dead by now. For whatever reason, we're not. Exit
274 // immediately, with the exit status set to the signal number with bit 8 203 // immediately, with the exit status set to the signal number with bit 8
275 // set. On the systems that we care about, this exit status is what is 204 // set. On the systems that we care about, this exit status is what is
276 // normally used to indicate an exit by this signal's default handler. 205 // normally used to indicate an exit by this signal's default handler.
277 // This mechanism isn't a de jure standard, but even in the worst case, it 206 // This mechanism isn't a de jure standard, but even in the worst case, it
278 // should at least result in an immediate exit. 207 // should at least result in an immediate exit.
279 LOG(WARNING) << "Still here, exiting really ungracefully."; 208 LOG(WARNING) << "Still here, exiting really ungracefully";
280 _exit(signal | (1 << 7)); 209 _exit(signal | (1 << 7));
281 } 210 }
282 } 211 }
283 212
213 // See comment in BrowserMain, where sigaction is called.
214 void SIGHUPHandler(int signal) {
215 GracefulShutdownHandler(signal, SIGHUP);
216 }
217
218 // See comment in BrowserMain, where sigaction is called.
219 void SIGINTHandler(int signal) {
220 GracefulShutdownHandler(signal, SIGINT);
221 }
222
223 // See comment in BrowserMain, where sigaction is called.
224 void SIGTERMHandler(int signal) {
225 GracefulShutdownHandler(signal, SIGTERM);
226 }
227
284 // Sets the file descriptor soft limit to |max_descriptors| or the OS hard 228 // Sets the file descriptor soft limit to |max_descriptors| or the OS hard
285 // limit, whichever is lower. 229 // limit, whichever is lower.
286 void SetFileDescriptorLimit(unsigned int max_descriptors) { 230 void SetFileDescriptorLimit(unsigned int max_descriptors) {
287 struct rlimit limits; 231 struct rlimit limits;
288 if (getrlimit(RLIMIT_NOFILE, &limits) == 0) { 232 if (getrlimit(RLIMIT_NOFILE, &limits) == 0) {
289 unsigned int new_limit = max_descriptors; 233 unsigned int new_limit = max_descriptors;
290 if (limits.rlim_max > 0 && limits.rlim_max < max_descriptors) { 234 if (limits.rlim_max > 0 && limits.rlim_max < max_descriptors) {
291 new_limit = limits.rlim_max; 235 new_limit = limits.rlim_max;
292 } 236 }
293 limits.rlim_cur = new_limit; 237 limits.rlim_cur = new_limit;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 std::wstring app_name = chrome::kBrowserAppName; 356 std::wstring app_name = chrome::kBrowserAppName;
413 std::string thread_name_string = WideToASCII(app_name + L"_BrowserMain"); 357 std::string thread_name_string = WideToASCII(app_name + L"_BrowserMain");
414 358
415 const char* thread_name = thread_name_string.c_str(); 359 const char* thread_name = thread_name_string.c_str();
416 PlatformThread::SetName(thread_name); 360 PlatformThread::SetName(thread_name);
417 main_message_loop.set_thread_name(thread_name); 361 main_message_loop.set_thread_name(thread_name);
418 362
419 // Register the main thread by instantiating it, but don't call any methods. 363 // Register the main thread by instantiating it, but don't call any methods.
420 ChromeThread main_thread(ChromeThread::UI, MessageLoop::current()); 364 ChromeThread main_thread(ChromeThread::UI, MessageLoop::current());
421 365
422 #if defined(OS_POSIX)
423 int pipefd[2];
424 int ret = pipe(pipefd);
425 if (ret < 0) {
426 PLOG(DFATAL) << "Failed to create pipe";
427 } else {
428 g_shutdown_pipe_read_fd = pipefd[0];
429 g_shutdown_pipe_write_fd = pipefd[1];
430 const size_t kShutdownDetectorThreadStackSize = 4096;
431 if (!PlatformThread::CreateNonJoinable(
432 kShutdownDetectorThreadStackSize,
433 new ShutdownDetector(g_shutdown_pipe_read_fd))) {
434 LOG(DFATAL) << "Failed to create shutdown detector task.";
435 }
436 }
437 #endif // defined(OS_POSIX)
438
439 FilePath user_data_dir; 366 FilePath user_data_dir;
440 #if defined(OS_WIN) 367 #if defined(OS_WIN)
441 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); 368 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
442 #else 369 #else
443 // Getting the user data dir can fail if the directory isn't 370 // Getting the user data dir can fail if the directory isn't
444 // creatable, for example; on Windows in code below we bring up a 371 // creatable, for example; on Windows in code below we bring up a
445 // dialog prompting the user to pick a different directory. 372 // dialog prompting the user to pick a different directory.
446 // However, ProcessSingleton needs a real user_data_dir on Mac/Linux, 373 // However, ProcessSingleton needs a real user_data_dir on Mac/Linux,
447 // so it's better to fail here than fail mysteriously elsewhere. 374 // so it's better to fail here than fail mysteriously elsewhere.
448 CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) 375 CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir))
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 if (metrics) 919 if (metrics)
993 metrics->Stop(); 920 metrics->Stop();
994 921
995 // browser_shutdown takes care of deleting browser_process, so we need to 922 // browser_shutdown takes care of deleting browser_process, so we need to
996 // release it. 923 // release it.
997 browser_process.release(); 924 browser_process.release();
998 browser_shutdown::Shutdown(); 925 browser_shutdown::Shutdown();
999 926
1000 return result_code; 927 return result_code;
1001 } 928 }
OLDNEW
« no previous file with comments | « build/common.gypi ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698