OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_process_impl.h" | 5 #include "chrome/browser/browser_process_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 #if defined(ENABLE_WEBRTC) | 122 #if defined(ENABLE_WEBRTC) |
123 #include "chrome/browser/media/webrtc_log_uploader.h" | 123 #include "chrome/browser/media/webrtc_log_uploader.h" |
124 #endif | 124 #endif |
125 | 125 |
126 #if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) | 126 #if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) |
127 // How often to check if the persistent instance of Chrome needs to restart | 127 // How often to check if the persistent instance of Chrome needs to restart |
128 // to install an update. | 128 // to install an update. |
129 static const int kUpdateCheckIntervalHours = 6; | 129 static const int kUpdateCheckIntervalHours = 6; |
130 #endif | 130 #endif |
131 | 131 |
132 #if defined(OS_WIN) | 132 #if defined(USE_X11) || defined(OS_WIN) |
133 // Attest to the fact that the call to the file thread to save preferences has | 133 // How long to wait for the File thread to complete during EndSession, on Linux |
134 // run, and it is safe to terminate. This avoids the potential of some other | 134 // and Windows. We have a timeout here because we're unable to run the UI |
135 // task prematurely terminating our waiting message loop by posting a | 135 // messageloop and there's some deadlock risk. Our only option is to exit |
136 // QuitTask(). | 136 // anyway. |
137 static bool g_end_session_file_thread_has_completed = false; | |
138 #endif | |
139 | |
140 #if defined(USE_X11) | |
141 // How long to wait for the File thread to complete during EndSession, on | |
142 // Linux. We have a timeout here because we're unable to run the UI messageloop | |
143 // and there's some deadlock risk. Our only option is to exit anyway. | |
144 static const int kEndSessionTimeoutSeconds = 10; | 137 static const int kEndSessionTimeoutSeconds = 10; |
145 #endif | 138 #endif |
146 | 139 |
147 using content::BrowserThread; | 140 using content::BrowserThread; |
148 using content::ChildProcessSecurityPolicy; | 141 using content::ChildProcessSecurityPolicy; |
149 using content::PluginService; | 142 using content::PluginService; |
150 using content::ResourceDispatcherHost; | 143 using content::ResourceDispatcherHost; |
151 | 144 |
152 BrowserProcessImpl::BrowserProcessImpl( | 145 BrowserProcessImpl::BrowserProcessImpl( |
153 base::SequencedTaskRunner* local_state_task_runner, | 146 base::SequencedTaskRunner* local_state_task_runner, |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 // Reset associated state right after actual thread is stopped, | 300 // Reset associated state right after actual thread is stopped, |
308 // as io_thread_.global_ cleanup happens in CleanUp on the IO | 301 // as io_thread_.global_ cleanup happens in CleanUp on the IO |
309 // thread, i.e. as the thread exits its message loop. | 302 // thread, i.e. as the thread exits its message loop. |
310 // | 303 // |
311 // This is important also because in various places, the | 304 // This is important also because in various places, the |
312 // IOThread object being NULL is considered synonymous with the | 305 // IOThread object being NULL is considered synonymous with the |
313 // IO thread having stopped. | 306 // IO thread having stopped. |
314 io_thread_.reset(); | 307 io_thread_.reset(); |
315 } | 308 } |
316 | 309 |
317 #if defined(OS_WIN) | 310 #if defined(USE_X11) || defined(OS_WIN) |
318 // Send a QuitTask to the given MessageLoop when the (file) thread has processed | |
319 // our (other) recent requests (to save preferences). | |
320 // Change the boolean so that the receiving thread will know that we did indeed | |
321 // send the QuitTask that terminated the message loop. | |
322 static void PostQuit(base::MessageLoop* message_loop) { | |
323 g_end_session_file_thread_has_completed = true; | |
324 message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); | |
325 } | |
326 #elif defined(USE_X11) | |
327 static void Signal(base::WaitableEvent* event) { | 311 static void Signal(base::WaitableEvent* event) { |
328 event->Signal(); | 312 event->Signal(); |
329 } | 313 } |
330 #endif | 314 #endif |
331 | 315 |
332 unsigned int BrowserProcessImpl::AddRefModule() { | 316 unsigned int BrowserProcessImpl::AddRefModule() { |
333 DCHECK(CalledOnValidThread()); | 317 DCHECK(CalledOnValidThread()); |
334 | 318 |
335 // CHECK(!IsShuttingDown()); | 319 // CHECK(!IsShuttingDown()); |
336 if (IsShuttingDown()) { | 320 if (IsShuttingDown()) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 local_state()->CommitPendingWrite(); | 382 local_state()->CommitPendingWrite(); |
399 #endif | 383 #endif |
400 } | 384 } |
401 | 385 |
402 // http://crbug.com/125207 | 386 // http://crbug.com/125207 |
403 base::ThreadRestrictions::ScopedAllowWait allow_wait; | 387 base::ThreadRestrictions::ScopedAllowWait allow_wait; |
404 | 388 |
405 // We must write that the profile and metrics service shutdown cleanly, | 389 // We must write that the profile and metrics service shutdown cleanly, |
406 // otherwise on startup we'll think we crashed. So we block until done and | 390 // otherwise on startup we'll think we crashed. So we block until done and |
407 // then proceed with normal shutdown. | 391 // then proceed with normal shutdown. |
408 #if defined(USE_X11) | 392 #if defined(USE_X11) || defined(OS_WIN) |
409 // Can't run a local loop on linux. Instead create a waitable event. | 393 // Create a waitable event to block on file writing being complete. |
| 394 // |
| 395 // On Windows, we previously posted a message to FILE and then ran a nested |
| 396 // message loop, waiting for that message to be processed until quitting. |
| 397 // However, doing so means that other messages will also be processed. In |
| 398 // particular, if the GPU process host notices that the GPU has been killed |
| 399 // during shutdown, it races exiting the nested loop with the process host |
| 400 // blocking the message loop attempting to re-establish a connection to the |
| 401 // GPU process synchronously. Because the system may not be allowing |
| 402 // processes to launch, this can result in a hang. See |
| 403 // http://crbug.com/318527. |
410 scoped_ptr<base::WaitableEvent> done_writing( | 404 scoped_ptr<base::WaitableEvent> done_writing( |
411 new base::WaitableEvent(false, false)); | 405 new base::WaitableEvent(false, false)); |
412 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 406 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
413 base::Bind(Signal, done_writing.get())); | 407 base::Bind(Signal, done_writing.get())); |
414 // If all file writes haven't cleared in the timeout, leak the WaitableEvent | 408 // If all file writes haven't cleared in the timeout, leak the WaitableEvent |
415 // so that there's no race to reference it in Signal(). | 409 // so that there's no race to reference it in Signal(). |
416 if (!done_writing->TimedWait( | 410 if (!done_writing->TimedWait( |
417 base::TimeDelta::FromSeconds(kEndSessionTimeoutSeconds))) { | 411 base::TimeDelta::FromSeconds(kEndSessionTimeoutSeconds))) { |
418 ignore_result(done_writing.release()); | 412 ignore_result(done_writing.release()); |
419 } | 413 } |
420 | |
421 #elif defined(OS_WIN) | |
422 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | |
423 base::Bind(PostQuit, base::MessageLoop::current())); | |
424 int quits_received = 0; | |
425 do { | |
426 base::MessageLoop::current()->Run(); | |
427 ++quits_received; | |
428 } while (!g_end_session_file_thread_has_completed); | |
429 // If we did get extra quits, then we should re-post them to the message loop. | |
430 while (--quits_received > 0) { | |
431 base::MessageLoop::current()->PostTask(FROM_HERE, | |
432 base::MessageLoop::QuitClosure()); | |
433 } | |
434 #else | 414 #else |
435 NOTIMPLEMENTED(); | 415 NOTIMPLEMENTED(); |
436 #endif | 416 #endif |
437 } | 417 } |
438 | 418 |
439 MetricsService* BrowserProcessImpl::metrics_service() { | 419 MetricsService* BrowserProcessImpl::metrics_service() { |
440 DCHECK(CalledOnValidThread()); | 420 DCHECK(CalledOnValidThread()); |
441 if (!created_metrics_service_) | 421 if (!created_metrics_service_) |
442 CreateMetricsService(); | 422 CreateMetricsService(); |
443 return metrics_service_.get(); | 423 return metrics_service_.get(); |
(...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1118 } | 1098 } |
1119 | 1099 |
1120 void BrowserProcessImpl::OnAutoupdateTimer() { | 1100 void BrowserProcessImpl::OnAutoupdateTimer() { |
1121 if (CanAutorestartForUpdate()) { | 1101 if (CanAutorestartForUpdate()) { |
1122 DLOG(WARNING) << "Detected update. Restarting browser."; | 1102 DLOG(WARNING) << "Detected update. Restarting browser."; |
1123 RestartBackgroundInstance(); | 1103 RestartBackgroundInstance(); |
1124 } | 1104 } |
1125 } | 1105 } |
1126 | 1106 |
1127 #endif // (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) | 1107 #endif // (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) |
OLD | NEW |