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

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

Issue 460154: Revert 34110 - Fix leak of ShutdownDetector. Broke Mac startup_test.... (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 | « no previous file | tools/valgrind/memcheck/suppressions.txt » ('j') | 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"
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 MessageLoopForUI::current()->Run(); 164 MessageLoopForUI::current()->Run();
165 #endif 165 #endif
166 } 166 }
167 167
168 #if defined(OS_POSIX) 168 #if defined(OS_POSIX)
169 // See comment in BrowserMain, where sigaction is called. 169 // See comment in BrowserMain, where sigaction is called.
170 void SIGCHLDHandler(int signal) { 170 void SIGCHLDHandler(int signal) {
171 } 171 }
172 172
173 int g_shutdown_pipe_write_fd = -1; 173 int g_shutdown_pipe_write_fd = -1;
174 int g_shutdown_pipe_read_fd = -1;
174 175
175 // Common code between SIG{HUP, INT, TERM}Handler. 176 // Common code between SIG{HUP, INT, TERM}Handler.
176 void GracefulShutdownHandler(int signal) { 177 void GracefulShutdownHandler(int signal) {
177 // Reinstall the default handler. We had one shot at graceful shutdown. 178 // Reinstall the default handler. We had one shot at graceful shutdown.
178 struct sigaction action; 179 struct sigaction action;
179 memset(&action, 0, sizeof(action)); 180 memset(&action, 0, sizeof(action));
180 action.sa_handler = SIG_DFL; 181 action.sa_handler = SIG_DFL;
181 CHECK(sigaction(signal, &action, NULL) == 0); 182 CHECK(sigaction(signal, &action, NULL) == 0);
182 183
183 RAW_CHECK(g_shutdown_pipe_write_fd != -1); 184 RAW_CHECK(g_shutdown_pipe_write_fd != -1);
185 RAW_CHECK(g_shutdown_pipe_read_fd != -1);
184 size_t bytes_written = 0; 186 size_t bytes_written = 0;
185 do { 187 do {
186 int rv = HANDLE_EINTR( 188 int rv = HANDLE_EINTR(
187 write(g_shutdown_pipe_write_fd, 189 write(g_shutdown_pipe_write_fd,
188 reinterpret_cast<const char*>(&signal) + bytes_written, 190 reinterpret_cast<const char*>(&signal) + bytes_written,
189 sizeof(signal) - bytes_written)); 191 sizeof(signal) - bytes_written));
190 RAW_CHECK(rv >= 0); 192 RAW_CHECK(rv >= 0);
191 bytes_written += rv; 193 bytes_written += rv;
192 } while (bytes_written < sizeof(signal)); 194 } while (bytes_written < sizeof(signal));
193 195
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 ssize_t ret; 241 ssize_t ret;
240 do { 242 do {
241 ret = HANDLE_EINTR( 243 ret = HANDLE_EINTR(
242 read(shutdown_fd_, 244 read(shutdown_fd_,
243 reinterpret_cast<char*>(&signal) + bytes_read, 245 reinterpret_cast<char*>(&signal) + bytes_read,
244 sizeof(signal) - bytes_read)); 246 sizeof(signal) - bytes_read));
245 if (ret < 0) { 247 if (ret < 0) {
246 NOTREACHED() << "Unexpected error: " << strerror(errno); 248 NOTREACHED() << "Unexpected error: " << strerror(errno);
247 break; 249 break;
248 } else if (ret == 0) { 250 } else if (ret == 0) {
249 // Normal shutdown. 251 NOTREACHED() << "Unexpected closure of shutdown pipe.";
250 break; 252 break;
251 } 253 }
252 bytes_read += ret; 254 bytes_read += ret;
253 } while (bytes_read < sizeof(signal)); 255 } while (bytes_read < sizeof(signal));
254 256
255 if (bytes_read == sizeof(signal)) { 257 LOG(INFO) << "Handling shutdown for signal " << signal << ".";
256 LOG(INFO) << "Handling shutdown for signal " << signal << ".";
257 258
258 if (!ChromeThread::PostTask( 259 if (!ChromeThread::PostTask(
259 ChromeThread::UI, FROM_HERE, 260 ChromeThread::UI, FROM_HERE,
260 NewRunnableFunction(BrowserList::CloseAllBrowsersAndExit))) { 261 NewRunnableFunction(BrowserList::CloseAllBrowsersAndExit))) {
261 // Without a UI thread to post the exit task to, there aren't many 262 // Without a UI thread to post the exit task to, there aren't many
262 // options. Raise the signal again. The default handler will pick it up 263 // options. Raise the signal again. The default handler will pick it up
263 // and cause an ungraceful exit. 264 // and cause an ungraceful exit.
264 LOG(WARNING) << "No UI thread, exiting ungracefully."; 265 LOG(WARNING) << "No UI thread, exiting ungracefully.";
265 PLOG_IF(ERROR, raise(signal) != 0) << "Failed to raise signal"; 266 kill(getpid(), signal);
266 267
267 // The signal may be handled on another thread. Give that a chance to 268 // The signal may be handled on another thread. Give that a chance to
268 // happen. 269 // happen.
269 sleep(3); 270 sleep(3);
270 271
271 // We really should be dead by now. For whatever reason, we're not. Exit 272 // We really should be dead by now. For whatever reason, we're not. Exit
272 // immediately, with the exit status set to the signal number with bit 8 273 // immediately, with the exit status set to the signal number with bit 8
273 // set. On the systems that we care about, this exit status is what is 274 // set. On the systems that we care about, this exit status is what is
274 // normally used to indicate an exit by this signal's default handler. 275 // normally used to indicate an exit by this signal's default handler.
275 // This mechanism isn't a de jure standard, but even in the worst case, it 276 // This mechanism isn't a de jure standard, but even in the worst case, it
276 // should at least result in an immediate exit. 277 // should at least result in an immediate exit.
277 LOG(WARNING) << "Still here, exiting really ungracefully."; 278 LOG(WARNING) << "Still here, exiting really ungracefully.";
278 _exit(signal | (1 << 7)); 279 _exit(signal | (1 << 7));
279 }
280 } 280 }
281
282 delete this;
283 } 281 }
284 282
285 // Sets the file descriptor soft limit to |max_descriptors| or the OS hard 283 // Sets the file descriptor soft limit to |max_descriptors| or the OS hard
286 // limit, whichever is lower. 284 // limit, whichever is lower.
287 void SetFileDescriptorLimit(unsigned int max_descriptors) { 285 void SetFileDescriptorLimit(unsigned int max_descriptors) {
288 struct rlimit limits; 286 struct rlimit limits;
289 if (getrlimit(RLIMIT_NOFILE, &limits) == 0) { 287 if (getrlimit(RLIMIT_NOFILE, &limits) == 0) {
290 unsigned int new_limit = max_descriptors; 288 unsigned int new_limit = max_descriptors;
291 if (limits.rlim_max > 0 && limits.rlim_max < max_descriptors) { 289 if (limits.rlim_max > 0 && limits.rlim_max < max_descriptors) {
292 new_limit = limits.rlim_max; 290 new_limit = limits.rlim_max;
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 const char* thread_name = thread_name_string.c_str(); 414 const char* thread_name = thread_name_string.c_str();
417 PlatformThread::SetName(thread_name); 415 PlatformThread::SetName(thread_name);
418 main_message_loop.set_thread_name(thread_name); 416 main_message_loop.set_thread_name(thread_name);
419 417
420 // Register the main thread by instantiating it, but don't call any methods. 418 // Register the main thread by instantiating it, but don't call any methods.
421 ChromeThread main_thread(ChromeThread::UI, MessageLoop::current()); 419 ChromeThread main_thread(ChromeThread::UI, MessageLoop::current());
422 420
423 #if defined(OS_POSIX) 421 #if defined(OS_POSIX)
424 int pipefd[2]; 422 int pipefd[2];
425 int ret = pipe(pipefd); 423 int ret = pipe(pipefd);
426 PlatformThreadHandle shutdown_detector_thread;
427 if (ret < 0) { 424 if (ret < 0) {
428 PLOG(DFATAL) << "Failed to create pipe"; 425 PLOG(DFATAL) << "Failed to create pipe";
429 } else { 426 } else {
427 g_shutdown_pipe_read_fd = pipefd[0];
428 g_shutdown_pipe_write_fd = pipefd[1];
430 const size_t kShutdownDetectorThreadStackSize = 4096; 429 const size_t kShutdownDetectorThreadStackSize = 4096;
431 if (PlatformThread::Create( 430 if (!PlatformThread::CreateNonJoinable(
432 kShutdownDetectorThreadStackSize, 431 kShutdownDetectorThreadStackSize,
433 new ShutdownDetector(pipefd[0]), 432 new ShutdownDetector(g_shutdown_pipe_read_fd))) {
434 &shutdown_detector_thread)) {
435 // Successfully spawned shutdown detector thread.
436 g_shutdown_pipe_write_fd = pipefd[1];
437 } else {
438 LOG(DFATAL) << "Failed to create shutdown detector task."; 433 LOG(DFATAL) << "Failed to create shutdown detector task.";
439 ret = HANDLE_EINTR(close(pipefd[0]));
440 PLOG_IF(ERROR, ret != 0) << "Failed to close shutdown read pipe";
441 ret = HANDLE_EINTR(close(pipefd[1]));
442 PLOG_IF(ERROR, ret != 0) << "Failed to close shutdown write pipe";
443 } 434 }
444 } 435 }
445 #endif // defined(OS_POSIX) 436 #endif // defined(OS_POSIX)
446 437
447 FilePath user_data_dir; 438 FilePath user_data_dir;
448 #if defined(OS_WIN) 439 #if defined(OS_WIN)
449 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); 440 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
450 #else 441 #else
451 // Getting the user data dir can fail if the directory isn't 442 // Getting the user data dir can fail if the directory isn't
452 // creatable, for example; on Windows in code below we bring up a 443 // creatable, for example; on Windows in code below we bring up a
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 &result_code)) { 957 &result_code)) {
967 // Call Recycle() here as late as possible, before going into the loop 958 // Call Recycle() here as late as possible, before going into the loop
968 // because Start() will add things to it while creating the main window. 959 // because Start() will add things to it while creating the main window.
969 if (pool) 960 if (pool)
970 pool->Recycle(); 961 pool->Recycle();
971 RunUIMessageLoop(browser_process.get()); 962 RunUIMessageLoop(browser_process.get());
972 } 963 }
973 } 964 }
974 chrome_browser_net_websocket_experiment::WebSocketExperimentRunner::Stop(); 965 chrome_browser_net_websocket_experiment::WebSocketExperimentRunner::Stop();
975 966
976 #if defined(OS_POSIX)
977 // If we initialized the shutdown pipe, then close it.
978 if (g_shutdown_pipe_write_fd != -1) {
979 ret = HANDLE_EINTR(close(g_shutdown_pipe_write_fd));
980 g_shutdown_pipe_write_fd = -1;
981 PLOG_IF(ERROR, ret != 0) << "Failed to close";
982 }
983 #endif // defined(OS_POSIX)
984
985 process_singleton.Cleanup(); 967 process_singleton.Cleanup();
986 968
987 Platform::DidEndMainMessageLoop(); 969 Platform::DidEndMainMessageLoop();
988 970
989 if (metrics) 971 if (metrics)
990 metrics->Stop(); 972 metrics->Stop();
991 973
992 // browser_shutdown takes care of deleting browser_process, so we need to 974 // browser_shutdown takes care of deleting browser_process, so we need to
993 // release it. 975 // release it.
994 browser_process.release(); 976 browser_process.release();
995 browser_shutdown::Shutdown(); 977 browser_shutdown::Shutdown();
996 978
997 return result_code; 979 return result_code;
998 } 980 }
OLDNEW
« no previous file with comments | « no previous file | tools/valgrind/memcheck/suppressions.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698