OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_posix.h" | 5 #include "chrome/browser/browser_main_posix.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <signal.h> | 8 #include <signal.h> |
9 #include <sys/resource.h> | 9 #include <sys/resource.h> |
10 | 10 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
82 const int shutdown_fd_; | 82 const int shutdown_fd_; |
83 | 83 |
84 DISALLOW_COPY_AND_ASSIGN(ShutdownDetector); | 84 DISALLOW_COPY_AND_ASSIGN(ShutdownDetector); |
85 }; | 85 }; |
86 | 86 |
87 ShutdownDetector::ShutdownDetector(int shutdown_fd) | 87 ShutdownDetector::ShutdownDetector(int shutdown_fd) |
88 : shutdown_fd_(shutdown_fd) { | 88 : shutdown_fd_(shutdown_fd) { |
89 CHECK_NE(shutdown_fd_, -1); | 89 CHECK_NE(shutdown_fd_, -1); |
90 } | 90 } |
91 | 91 |
92 | |
93 // These functions are used to help us diagnose crash dumps that happen | |
94 // during the shutdown process. | |
95 #define NOINLINE __attribute__((noinline)) | |
96 | |
97 NOINLINE void ShutdownFDReadError() { | |
98 sleep(UINT_MAX); | |
willchan no longer on Chromium
2011/05/04 21:06:49
I think you need <limits.h> for this constant and
DaveMoore
2011/05/09 17:41:42
Done. I kept the sleep() call, added the asm("") a
| |
99 } | |
100 | |
101 NOINLINE void ShutdownFDClosedError() { | |
102 sleep(UINT_MAX); | |
103 } | |
104 | |
105 NOINLINE void CloseAllBrowsersAndExitPosted() { | |
106 sleep(UINT_MAX); | |
107 } | |
108 | |
92 void ShutdownDetector::ThreadMain() { | 109 void ShutdownDetector::ThreadMain() { |
93 base::PlatformThread::SetName("CrShutdownDetector"); | 110 base::PlatformThread::SetName("CrShutdownDetector"); |
94 | 111 |
95 int signal; | 112 int signal; |
96 size_t bytes_read = 0; | 113 size_t bytes_read = 0; |
97 ssize_t ret; | 114 ssize_t ret; |
98 do { | 115 do { |
99 ret = HANDLE_EINTR( | 116 ret = HANDLE_EINTR( |
100 read(shutdown_fd_, | 117 read(shutdown_fd_, |
101 reinterpret_cast<char*>(&signal) + bytes_read, | 118 reinterpret_cast<char*>(&signal) + bytes_read, |
102 sizeof(signal) - bytes_read)); | 119 sizeof(signal) - bytes_read)); |
103 if (ret < 0) { | 120 if (ret < 0) { |
104 NOTREACHED() << "Unexpected error: " << strerror(errno); | 121 NOTREACHED() << "Unexpected error: " << strerror(errno); |
122 ShutdownFDReadError(); | |
105 break; | 123 break; |
106 } else if (ret == 0) { | 124 } else if (ret == 0) { |
107 NOTREACHED() << "Unexpected closure of shutdown pipe."; | 125 NOTREACHED() << "Unexpected closure of shutdown pipe."; |
126 ShutdownFDClosedError(); | |
108 break; | 127 break; |
109 } | 128 } |
110 bytes_read += ret; | 129 bytes_read += ret; |
111 } while (bytes_read < sizeof(signal)); | 130 } while (bytes_read < sizeof(signal)); |
112 | 131 |
113 VLOG(1) << "Handling shutdown for signal " << signal << "."; | 132 VLOG(1) << "Handling shutdown for signal " << signal << "."; |
114 | 133 |
115 if (!BrowserThread::PostTask( | 134 if (!BrowserThread::PostTask( |
116 BrowserThread::UI, FROM_HERE, | 135 BrowserThread::UI, FROM_HERE, |
117 NewRunnableFunction(BrowserList::CloseAllBrowsersAndExit))) { | 136 NewRunnableFunction(BrowserList::CloseAllBrowsersAndExit))) { |
118 // Without a UI thread to post the exit task to, there aren't many | 137 // Without a UI thread to post the exit task to, there aren't many |
119 // options. Raise the signal again. The default handler will pick it up | 138 // options. Raise the signal again. The default handler will pick it up |
120 // and cause an ungraceful exit. | 139 // and cause an ungraceful exit. |
121 RAW_LOG(WARNING, "No UI thread, exiting ungracefully."); | 140 RAW_LOG(WARNING, "No UI thread, exiting ungracefully."); |
122 kill(getpid(), signal); | 141 kill(getpid(), signal); |
123 | 142 |
124 // The signal may be handled on another thread. Give that a chance to | 143 // The signal may be handled on another thread. Give that a chance to |
125 // happen. | 144 // happen. |
126 sleep(3); | 145 sleep(3); |
127 | 146 |
128 // We really should be dead by now. For whatever reason, we're not. Exit | 147 // We really should be dead by now. For whatever reason, we're not. Exit |
129 // immediately, with the exit status set to the signal number with bit 8 | 148 // immediately, with the exit status set to the signal number with bit 8 |
130 // set. On the systems that we care about, this exit status is what is | 149 // set. On the systems that we care about, this exit status is what is |
131 // normally used to indicate an exit by this signal's default handler. | 150 // normally used to indicate an exit by this signal's default handler. |
132 // This mechanism isn't a de jure standard, but even in the worst case, it | 151 // This mechanism isn't a de jure standard, but even in the worst case, it |
133 // should at least result in an immediate exit. | 152 // should at least result in an immediate exit. |
134 RAW_LOG(WARNING, "Still here, exiting really ungracefully."); | 153 RAW_LOG(WARNING, "Still here, exiting really ungracefully."); |
135 _exit(signal | (1 << 7)); | 154 _exit(signal | (1 << 7)); |
136 } | 155 } |
156 CloseAllBrowsersAndExitPosted(); | |
137 } | 157 } |
138 | 158 |
139 // Sets the file descriptor soft limit to |max_descriptors| or the OS hard | 159 // Sets the file descriptor soft limit to |max_descriptors| or the OS hard |
140 // limit, whichever is lower. | 160 // limit, whichever is lower. |
141 void SetFileDescriptorLimit(unsigned int max_descriptors) { | 161 void SetFileDescriptorLimit(unsigned int max_descriptors) { |
142 struct rlimit limits; | 162 struct rlimit limits; |
143 if (getrlimit(RLIMIT_NOFILE, &limits) == 0) { | 163 if (getrlimit(RLIMIT_NOFILE, &limits) == 0) { |
144 unsigned int new_limit = max_descriptors; | 164 unsigned int new_limit = max_descriptors; |
145 if (limits.rlim_max > 0 && limits.rlim_max < max_descriptors) { | 165 if (limits.rlim_max > 0 && limits.rlim_max < max_descriptors) { |
146 new_limit = limits.rlim_max; | 166 new_limit = limits.rlim_max; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
228 new ShutdownDetector(g_shutdown_pipe_read_fd))) { | 248 new ShutdownDetector(g_shutdown_pipe_read_fd))) { |
229 LOG(DFATAL) << "Failed to create shutdown detector task."; | 249 LOG(DFATAL) << "Failed to create shutdown detector task."; |
230 } | 250 } |
231 } | 251 } |
232 | 252 |
233 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) | 253 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
234 printing::PrintingContextCairo::SetCreatePrintDialogFunction( | 254 printing::PrintingContextCairo::SetCreatePrintDialogFunction( |
235 &PrintDialogGtk::CreatePrintDialog); | 255 &PrintDialogGtk::CreatePrintDialog); |
236 #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) | 256 #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) |
237 } | 257 } |
OLD | NEW |