| 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 |