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 "content/browser/browser_main_loop.h" | 5 #include "content/browser/browser_main_loop.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
12 #include "base/metrics/field_trial.h" | 12 #include "base/metrics/field_trial.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "base/threading/thread_restrictions.h" | 14 #include "base/threading/thread_restrictions.h" |
15 #include "content/browser/browser_thread_impl.h" | 15 #include "content/browser/browser_thread_impl.h" |
| 16 #include "content/browser/download/download_file_manager.h" |
| 17 #include "content/browser/download/save_file_manager.h" |
16 #include "content/browser/in_process_webkit/webkit_thread.h" | 18 #include "content/browser/in_process_webkit/webkit_thread.h" |
| 19 #include "content/browser/plugin_service_impl.h" |
| 20 #include "content/browser/renderer_host/resource_dispatcher_host.h" |
17 #include "content/browser/trace_controller.h" | 21 #include "content/browser/trace_controller.h" |
18 #include "content/common/hi_res_timer_manager.h" | 22 #include "content/common/hi_res_timer_manager.h" |
19 #include "content/common/sandbox_policy.h" | 23 #include "content/common/sandbox_policy.h" |
20 #include "content/public/browser/browser_main_parts.h" | 24 #include "content/public/browser/browser_main_parts.h" |
21 #include "content/public/browser/browser_shutdown.h" | 25 #include "content/public/browser/browser_shutdown.h" |
22 #include "content/public/browser/content_browser_client.h" | 26 #include "content/public/browser/content_browser_client.h" |
23 #include "content/public/common/content_switches.h" | 27 #include "content/public/common/content_switches.h" |
24 #include "content/public/common/main_function_params.h" | 28 #include "content/public/common/main_function_params.h" |
25 #include "content/public/common/result_codes.h" | 29 #include "content/public/common/result_codes.h" |
26 #include "crypto/nss_util.h" | 30 #include "crypto/nss_util.h" |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 | 287 |
284 system_monitor_.reset(new base::SystemMonitor); | 288 system_monitor_.reset(new base::SystemMonitor); |
285 hi_res_timer_manager_.reset(new HighResolutionTimerManager); | 289 hi_res_timer_manager_.reset(new HighResolutionTimerManager); |
286 | 290 |
287 network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); | 291 network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); |
288 | 292 |
289 #if defined(OS_WIN) | 293 #if defined(OS_WIN) |
290 system_message_window_.reset(new SystemMessageWindowWin); | 294 system_message_window_.reset(new SystemMessageWindowWin); |
291 #endif | 295 #endif |
292 | 296 |
| 297 // Prior to any processing happening on the io thread, we create the |
| 298 // plugin service as it is predominantly used from the io thread, |
| 299 // but must be created on the main thread. The service ctor is |
| 300 // inexpensive and does not invoke the io_thread() accessor. |
| 301 PluginService::GetInstance()->Init(); |
| 302 |
293 if (parts_.get()) | 303 if (parts_.get()) |
294 parts_->PostMainMessageLoopStart(); | 304 parts_->PostMainMessageLoopStart(); |
295 } | 305 } |
296 | 306 |
297 void BrowserMainLoop::RunMainMessageLoopParts( | 307 void BrowserMainLoop::RunMainMessageLoopParts( |
298 bool* completed_main_message_loop) { | 308 bool* completed_main_message_loop) { |
299 if (parts_.get()) | 309 if (parts_.get()) |
300 parts_->PreCreateThreads(); | 310 parts_->PreCreateThreads(); |
301 | 311 |
302 base::Thread::Options default_options; | 312 base::Thread::Options default_options; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 break; | 361 break; |
352 case BrowserThread::UI: | 362 case BrowserThread::UI: |
353 case BrowserThread::ID_COUNT: | 363 case BrowserThread::ID_COUNT: |
354 default: | 364 default: |
355 NOTREACHED(); | 365 NOTREACHED(); |
356 break; | 366 break; |
357 } | 367 } |
358 | 368 |
359 BrowserThread::ID id = static_cast<BrowserThread::ID>(thread_id); | 369 BrowserThread::ID id = static_cast<BrowserThread::ID>(thread_id); |
360 | 370 |
361 if (parts_.get()) | |
362 parts_->PreStartThread(id); | |
363 | |
364 if (thread_id == BrowserThread::WEBKIT_DEPRECATED) { | 371 if (thread_id == BrowserThread::WEBKIT_DEPRECATED) { |
365 webkit_thread_.reset(new WebKitThread); | 372 webkit_thread_.reset(new WebKitThread); |
366 webkit_thread_->Initialize(); | 373 webkit_thread_->Initialize(); |
367 } else if (thread_to_start) { | 374 } else if (thread_to_start) { |
368 (*thread_to_start).reset(new BrowserProcessSubThread(id)); | 375 (*thread_to_start).reset(new BrowserProcessSubThread(id)); |
369 (*thread_to_start)->StartWithOptions(*options); | 376 (*thread_to_start)->StartWithOptions(*options); |
370 } else { | 377 } else { |
371 NOTREACHED(); | 378 NOTREACHED(); |
372 } | 379 } |
| 380 } |
373 | 381 |
374 if (parts_.get()) | 382 BrowserThreadsStarted(); |
375 parts_->PostStartThread(id); | |
376 } | |
377 | 383 |
378 if (parts_.get()) | 384 if (parts_.get()) |
379 parts_->PreMainMessageLoopRun(); | 385 parts_->PreMainMessageLoopRun(); |
380 | 386 |
381 TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); | 387 TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); |
382 // If the UI thread blocks, the whole UI is unresponsive. | 388 // If the UI thread blocks, the whole UI is unresponsive. |
383 // Do not allow disk IO from the UI thread. | 389 // Do not allow disk IO from the UI thread. |
384 base::ThreadRestrictions::SetIOAllowed(false); | 390 base::ThreadRestrictions::SetIOAllowed(false); |
385 | 391 |
386 bool ran_main_loop = false; | 392 bool ran_main_loop = false; |
(...skipping 16 matching lines...) Expand all Loading... |
403 // need to be able to perform IO. | 409 // need to be able to perform IO. |
404 base::ThreadRestrictions::SetIOAllowed(true); | 410 base::ThreadRestrictions::SetIOAllowed(true); |
405 BrowserThread::PostTask( | 411 BrowserThread::PostTask( |
406 BrowserThread::IO, FROM_HERE, | 412 BrowserThread::IO, FROM_HERE, |
407 base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed), | 413 base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed), |
408 true)); | 414 true)); |
409 | 415 |
410 if (parts_.get()) | 416 if (parts_.get()) |
411 parts_->PostMainMessageLoopRun(); | 417 parts_->PostMainMessageLoopRun(); |
412 | 418 |
| 419 // Cancel pending requests and prevent new requests. |
| 420 if (resource_dispatcher_host_.get()) |
| 421 resource_dispatcher_host_.get()->Shutdown(); |
| 422 |
413 // Must be size_t so we can subtract from it. | 423 // Must be size_t so we can subtract from it. |
414 for (size_t thread_id = BrowserThread::ID_COUNT - 1; | 424 for (size_t thread_id = BrowserThread::ID_COUNT - 1; |
415 thread_id >= (BrowserThread::UI + 1); | 425 thread_id >= (BrowserThread::UI + 1); |
416 --thread_id) { | 426 --thread_id) { |
417 // Find the thread object we want to stop. Looping over all valid | 427 // Find the thread object we want to stop. Looping over all valid |
418 // BrowserThread IDs and DCHECKing on a missing case in the switch | 428 // BrowserThread IDs and DCHECKing on a missing case in the switch |
419 // statement helps avoid a mismatch between this code and the | 429 // statement helps avoid a mismatch between this code and the |
420 // BrowserThread::ID enumeration. | 430 // BrowserThread::ID enumeration. |
421 // | 431 // |
422 // The destruction order is the reverse order of occurrence in the | 432 // The destruction order is the reverse order of occurrence in the |
(...skipping 15 matching lines...) Expand all Loading... |
438 // | 448 // |
439 // - (Not sure why DB stops last.) | 449 // - (Not sure why DB stops last.) |
440 scoped_ptr<BrowserProcessSubThread>* thread_to_stop = NULL; | 450 scoped_ptr<BrowserProcessSubThread>* thread_to_stop = NULL; |
441 switch (thread_id) { | 451 switch (thread_id) { |
442 case BrowserThread::DB: | 452 case BrowserThread::DB: |
443 thread_to_stop = &db_thread_; | 453 thread_to_stop = &db_thread_; |
444 break; | 454 break; |
445 case BrowserThread::WEBKIT_DEPRECATED: | 455 case BrowserThread::WEBKIT_DEPRECATED: |
446 // Special case as WebKitThread is a separate | 456 // Special case as WebKitThread is a separate |
447 // type. |thread_to_stop| is not used in this case. | 457 // type. |thread_to_stop| is not used in this case. |
| 458 |
| 459 // Need to destroy ResourceDispatcherHost before PluginService |
| 460 // and since it caches a pointer to it. |
| 461 resource_dispatcher_host_.reset(); |
448 break; | 462 break; |
449 case BrowserThread::FILE_USER_BLOCKING: | 463 case BrowserThread::FILE_USER_BLOCKING: |
450 thread_to_stop = &file_user_blocking_thread_; | 464 thread_to_stop = &file_user_blocking_thread_; |
451 break; | 465 break; |
452 case BrowserThread::FILE: | 466 case BrowserThread::FILE: |
453 thread_to_stop = &file_thread_; | 467 thread_to_stop = &file_thread_; |
| 468 |
| 469 // Clean up state that lives on or uses the file_thread_ before |
| 470 // it goes away. |
| 471 if (resource_dispatcher_host_.get()) { |
| 472 resource_dispatcher_host_.get()->download_file_manager()->Shutdown(); |
| 473 resource_dispatcher_host_.get()->save_file_manager()->Shutdown(); |
| 474 } |
454 break; | 475 break; |
455 case BrowserThread::PROCESS_LAUNCHER: | 476 case BrowserThread::PROCESS_LAUNCHER: |
456 thread_to_stop = &process_launcher_thread_; | 477 thread_to_stop = &process_launcher_thread_; |
457 break; | 478 break; |
458 case BrowserThread::CACHE: | 479 case BrowserThread::CACHE: |
459 thread_to_stop = &cache_thread_; | 480 thread_to_stop = &cache_thread_; |
460 break; | 481 break; |
461 case BrowserThread::IO: | 482 case BrowserThread::IO: |
462 thread_to_stop = &io_thread_; | 483 thread_to_stop = &io_thread_; |
463 break; | 484 break; |
464 case BrowserThread::UI: | 485 case BrowserThread::UI: |
465 case BrowserThread::ID_COUNT: | 486 case BrowserThread::ID_COUNT: |
466 default: | 487 default: |
467 NOTREACHED(); | 488 NOTREACHED(); |
468 break; | 489 break; |
469 } | 490 } |
470 | 491 |
471 BrowserThread::ID id = static_cast<BrowserThread::ID>(thread_id); | 492 BrowserThread::ID id = static_cast<BrowserThread::ID>(thread_id); |
472 | 493 |
473 if (parts_.get()) | |
474 parts_->PreStopThread(id); | |
475 | |
476 if (id == BrowserThread::WEBKIT_DEPRECATED) { | 494 if (id == BrowserThread::WEBKIT_DEPRECATED) { |
477 webkit_thread_.reset(); | 495 webkit_thread_.reset(); |
478 } else if (thread_to_stop) { | 496 } else if (thread_to_stop) { |
479 thread_to_stop->reset(); | 497 thread_to_stop->reset(); |
480 } else { | 498 } else { |
481 NOTREACHED(); | 499 NOTREACHED(); |
482 } | 500 } |
483 | |
484 if (parts_.get()) | |
485 parts_->PostStopThread(id); | |
486 } | 501 } |
487 | 502 |
488 if (parts_.get()) | 503 if (parts_.get()) |
489 parts_->PostDestroyThreads(); | 504 parts_->PostDestroyThreads(); |
490 } | 505 } |
491 | 506 |
492 void BrowserMainLoop::InitializeMainThread() { | 507 void BrowserMainLoop::InitializeMainThread() { |
493 const char* kThreadName = "CrBrowserMain"; | 508 const char* kThreadName = "CrBrowserMain"; |
494 base::PlatformThread::SetName(kThreadName); | 509 base::PlatformThread::SetName(kThreadName); |
495 main_message_loop_->set_thread_name(kThreadName); | 510 main_message_loop_->set_thread_name(kThreadName); |
496 | 511 |
497 // Register the main thread by instantiating it, but don't call any methods. | 512 // Register the main thread by instantiating it, but don't call any methods. |
498 main_thread_.reset(new BrowserThreadImpl(BrowserThread::UI, | 513 main_thread_.reset(new BrowserThreadImpl(BrowserThread::UI, |
499 MessageLoop::current())); | 514 MessageLoop::current())); |
500 } | 515 } |
501 | 516 |
| 517 |
| 518 void BrowserMainLoop::BrowserThreadsStarted() { |
| 519 // RDH needs the IO thread to be created. |
| 520 resource_dispatcher_host_.reset(new ResourceDispatcherHost()); |
| 521 } |
| 522 |
502 void BrowserMainLoop::InitializeToolkit() { | 523 void BrowserMainLoop::InitializeToolkit() { |
503 // TODO(evan): this function is rather subtle, due to the variety | 524 // TODO(evan): this function is rather subtle, due to the variety |
504 // of intersecting ifdefs we have. To keep it easy to follow, there | 525 // of intersecting ifdefs we have. To keep it easy to follow, there |
505 // are no #else branches on any #ifs. | 526 // are no #else branches on any #ifs. |
506 // TODO(stevenjb): Move platform specific code into platform specific Parts | 527 // TODO(stevenjb): Move platform specific code into platform specific Parts |
507 // (Need to add InitializeToolkit stage to BrowserParts). | 528 // (Need to add InitializeToolkit stage to BrowserParts). |
508 #if defined(OS_LINUX) || defined(OS_OPENBSD) | 529 #if defined(OS_LINUX) || defined(OS_OPENBSD) |
509 // Glib type system initialization. Needed at least for gconf, | 530 // Glib type system initialization. Needed at least for gconf, |
510 // used in net/proxy/proxy_config_service_linux.cc. Most likely | 531 // used in net/proxy/proxy_config_service_linux.cc. Most likely |
511 // this is superfluous as gtk_init() ought to do this. It's | 532 // this is superfluous as gtk_init() ought to do this. It's |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
548 MessageLoopForUI::current()->PostTask(FROM_HERE, *parameters_.ui_task); | 569 MessageLoopForUI::current()->PostTask(FROM_HERE, *parameters_.ui_task); |
549 | 570 |
550 #if defined(OS_MACOSX) | 571 #if defined(OS_MACOSX) |
551 MessageLoopForUI::current()->Run(); | 572 MessageLoopForUI::current()->Run(); |
552 #else | 573 #else |
553 MessageLoopForUI::current()->RunWithDispatcher(NULL); | 574 MessageLoopForUI::current()->RunWithDispatcher(NULL); |
554 #endif | 575 #endif |
555 } | 576 } |
556 | 577 |
557 } // namespace content | 578 } // namespace content |
OLD | NEW |