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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 #endif | 367 #endif |
358 case BrowserThread::UI: | 368 case BrowserThread::UI: |
359 case BrowserThread::ID_COUNT: | 369 case BrowserThread::ID_COUNT: |
360 default: | 370 default: |
361 NOTREACHED(); | 371 NOTREACHED(); |
362 break; | 372 break; |
363 } | 373 } |
364 | 374 |
365 BrowserThread::ID id = static_cast<BrowserThread::ID>(thread_id); | 375 BrowserThread::ID id = static_cast<BrowserThread::ID>(thread_id); |
366 | 376 |
367 if (parts_.get()) | |
368 parts_->PreStartThread(id); | |
369 | |
370 if (thread_id == BrowserThread::WEBKIT_DEPRECATED) { | 377 if (thread_id == BrowserThread::WEBKIT_DEPRECATED) { |
371 webkit_thread_.reset(new WebKitThread); | 378 webkit_thread_.reset(new WebKitThread); |
372 webkit_thread_->Initialize(); | 379 webkit_thread_->Initialize(); |
373 } else if (thread_to_start) { | 380 } else if (thread_to_start) { |
374 (*thread_to_start).reset(new BrowserProcessSubThread(id)); | 381 (*thread_to_start).reset(new BrowserProcessSubThread(id)); |
375 (*thread_to_start)->StartWithOptions(*options); | 382 (*thread_to_start)->StartWithOptions(*options); |
376 } else { | 383 } else { |
377 NOTREACHED(); | 384 NOTREACHED(); |
378 } | 385 } |
379 | |
380 if (parts_.get()) | |
381 parts_->PostStartThread(id); | |
382 } | 386 } |
383 | 387 |
384 if (parts_.get()) | 388 if (parts_.get()) |
385 parts_->PreMainMessageLoopRun(); | 389 parts_->PreMainMessageLoopRun(); |
386 | 390 |
387 TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); | 391 TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); |
388 // If the UI thread blocks, the whole UI is unresponsive. | 392 // If the UI thread blocks, the whole UI is unresponsive. |
389 // Do not allow disk IO from the UI thread. | 393 // Do not allow disk IO from the UI thread. |
390 base::ThreadRestrictions::SetIOAllowed(false); | 394 base::ThreadRestrictions::SetIOAllowed(false); |
391 | 395 |
(...skipping 17 matching lines...) Expand all Loading... |
409 // need to be able to perform IO. | 413 // need to be able to perform IO. |
410 base::ThreadRestrictions::SetIOAllowed(true); | 414 base::ThreadRestrictions::SetIOAllowed(true); |
411 BrowserThread::PostTask( | 415 BrowserThread::PostTask( |
412 BrowserThread::IO, FROM_HERE, | 416 BrowserThread::IO, FROM_HERE, |
413 base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed), | 417 base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed), |
414 true)); | 418 true)); |
415 | 419 |
416 if (parts_.get()) | 420 if (parts_.get()) |
417 parts_->PostMainMessageLoopRun(); | 421 parts_->PostMainMessageLoopRun(); |
418 | 422 |
| 423 // Cancel pending requests and prevent new requests. |
| 424 ResourceDispatcherHost* rdh = ResourceDispatcherHost::IsCreated() ? |
| 425 ResourceDispatcherHost::Get() : NULL; |
| 426 if (rdh) |
| 427 rdh->Shutdown(); |
| 428 |
419 // Must be size_t so we can subtract from it. | 429 // Must be size_t so we can subtract from it. |
420 for (size_t thread_id = BrowserThread::ID_COUNT - 1; | 430 for (size_t thread_id = BrowserThread::ID_COUNT - 1; |
421 thread_id >= (BrowserThread::UI + 1); | 431 thread_id >= (BrowserThread::UI + 1); |
422 --thread_id) { | 432 --thread_id) { |
423 // Find the thread object we want to stop. Looping over all valid | 433 // Find the thread object we want to stop. Looping over all valid |
424 // BrowserThread IDs and DCHECKing on a missing case in the switch | 434 // BrowserThread IDs and DCHECKing on a missing case in the switch |
425 // statement helps avoid a mismatch between this code and the | 435 // statement helps avoid a mismatch between this code and the |
426 // BrowserThread::ID enumeration. | 436 // BrowserThread::ID enumeration. |
427 // | 437 // |
428 // The destruction order is the reverse order of occurrence in the | 438 // The destruction order is the reverse order of occurrence in the |
(...skipping 16 matching lines...) Expand all Loading... |
445 // | 455 // |
446 // - (Not sure why DB stops last.) | 456 // - (Not sure why DB stops last.) |
447 scoped_ptr<BrowserProcessSubThread>* thread_to_stop = NULL; | 457 scoped_ptr<BrowserProcessSubThread>* thread_to_stop = NULL; |
448 switch (thread_id) { | 458 switch (thread_id) { |
449 case BrowserThread::DB: | 459 case BrowserThread::DB: |
450 thread_to_stop = &db_thread_; | 460 thread_to_stop = &db_thread_; |
451 break; | 461 break; |
452 case BrowserThread::WEBKIT_DEPRECATED: | 462 case BrowserThread::WEBKIT_DEPRECATED: |
453 // Special case as WebKitThread is a separate | 463 // Special case as WebKitThread is a separate |
454 // type. |thread_to_stop| is not used in this case. | 464 // type. |thread_to_stop| is not used in this case. |
| 465 |
| 466 // Need to destroy ResourceDispatcherHost before PluginService |
| 467 // and since it caches a pointer to it. |
| 468 if (rdh) |
| 469 delete rdh; |
455 break; | 470 break; |
456 case BrowserThread::FILE_USER_BLOCKING: | 471 case BrowserThread::FILE_USER_BLOCKING: |
457 thread_to_stop = &file_user_blocking_thread_; | 472 thread_to_stop = &file_user_blocking_thread_; |
458 break; | 473 break; |
459 case BrowserThread::FILE: | 474 case BrowserThread::FILE: |
460 thread_to_stop = &file_thread_; | 475 thread_to_stop = &file_thread_; |
| 476 |
| 477 // Clean up state that lives on or uses the file_thread_ before |
| 478 // it goes away. |
| 479 if (rdh) { |
| 480 rdh->download_file_manager()->Shutdown(); |
| 481 rdh->save_file_manager()->Shutdown(); |
| 482 } |
461 break; | 483 break; |
462 case BrowserThread::PROCESS_LAUNCHER: | 484 case BrowserThread::PROCESS_LAUNCHER: |
463 thread_to_stop = &process_launcher_thread_; | 485 thread_to_stop = &process_launcher_thread_; |
464 break; | 486 break; |
465 case BrowserThread::CACHE: | 487 case BrowserThread::CACHE: |
466 thread_to_stop = &cache_thread_; | 488 thread_to_stop = &cache_thread_; |
467 break; | 489 break; |
468 case BrowserThread::IO: | 490 case BrowserThread::IO: |
469 thread_to_stop = &io_thread_; | 491 thread_to_stop = &io_thread_; |
470 break; | 492 break; |
471 #if defined(OS_CHROMEOS) | 493 #if defined(OS_CHROMEOS) |
472 case BrowserThread::WEB_SOCKET_PROXY: | 494 case BrowserThread::WEB_SOCKET_PROXY: |
473 thread_to_stop = &web_socket_proxy_thread_; | 495 thread_to_stop = &web_socket_proxy_thread_; |
474 break; | 496 break; |
475 #endif | 497 #endif |
476 case BrowserThread::UI: | 498 case BrowserThread::UI: |
477 case BrowserThread::ID_COUNT: | 499 case BrowserThread::ID_COUNT: |
478 default: | 500 default: |
479 NOTREACHED(); | 501 NOTREACHED(); |
480 break; | 502 break; |
481 } | 503 } |
482 | 504 |
483 BrowserThread::ID id = static_cast<BrowserThread::ID>(thread_id); | 505 BrowserThread::ID id = static_cast<BrowserThread::ID>(thread_id); |
484 | 506 |
485 if (parts_.get()) | |
486 parts_->PreStopThread(id); | |
487 | |
488 if (id == BrowserThread::WEBKIT_DEPRECATED) { | 507 if (id == BrowserThread::WEBKIT_DEPRECATED) { |
489 webkit_thread_.reset(); | 508 webkit_thread_.reset(); |
490 } else if (thread_to_stop) { | 509 } else if (thread_to_stop) { |
491 thread_to_stop->reset(); | 510 thread_to_stop->reset(); |
492 } else { | 511 } else { |
493 NOTREACHED(); | 512 NOTREACHED(); |
494 } | 513 } |
495 | |
496 if (parts_.get()) | |
497 parts_->PostStopThread(id); | |
498 } | 514 } |
499 | 515 |
500 if (parts_.get()) | 516 if (parts_.get()) |
501 parts_->PostDestroyThreads(); | 517 parts_->PostDestroyThreads(); |
502 } | 518 } |
503 | 519 |
504 void BrowserMainLoop::InitializeMainThread() { | 520 void BrowserMainLoop::InitializeMainThread() { |
505 const char* kThreadName = "CrBrowserMain"; | 521 const char* kThreadName = "CrBrowserMain"; |
506 base::PlatformThread::SetName(kThreadName); | 522 base::PlatformThread::SetName(kThreadName); |
507 main_message_loop_->set_thread_name(kThreadName); | 523 main_message_loop_->set_thread_name(kThreadName); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 MessageLoopForUI::current()->PostTask(FROM_HERE, *parameters_.ui_task); | 576 MessageLoopForUI::current()->PostTask(FROM_HERE, *parameters_.ui_task); |
561 | 577 |
562 #if defined(OS_MACOSX) | 578 #if defined(OS_MACOSX) |
563 MessageLoopForUI::current()->Run(); | 579 MessageLoopForUI::current()->Run(); |
564 #else | 580 #else |
565 MessageLoopForUI::current()->RunWithDispatcher(NULL); | 581 MessageLoopForUI::current()->RunWithDispatcher(NULL); |
566 #endif | 582 #endif |
567 } | 583 } |
568 | 584 |
569 } // namespace content | 585 } // namespace content |
OLD | NEW |