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

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

Issue 170023002: Don't use nested message loop during EndSession (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 months 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 | 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) 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
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
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
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
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)
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698