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

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

Issue 8477004: Have content/ create and destroy its own threads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Introduce and use BrowserThreadDelegate, BMP::Pre/PostStartThread, to make this a safe refactoring. Created 9 years, 1 month 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
OLDNEW
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 "chrome/browser/io_thread.h" 5 #include "chrome/browser/io_thread.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 private: 309 private:
310 IOThread* const io_thread_; // Weak pointer, owned by BrowserProcess. 310 IOThread* const io_thread_; // Weak pointer, owned by BrowserProcess.
311 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; 311 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
312 312
313 base::debug::LeakTracker<SystemURLRequestContextGetter> leak_tracker_; 313 base::debug::LeakTracker<SystemURLRequestContextGetter> leak_tracker_;
314 }; 314 };
315 315
316 SystemURLRequestContextGetter::SystemURLRequestContextGetter( 316 SystemURLRequestContextGetter::SystemURLRequestContextGetter(
317 IOThread* io_thread) 317 IOThread* io_thread)
318 : io_thread_(io_thread), 318 : io_thread_(io_thread),
319 io_message_loop_proxy_(io_thread->message_loop_proxy()) { 319 io_message_loop_proxy_(
320 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)) {
320 } 321 }
321 322
322 SystemURLRequestContextGetter::~SystemURLRequestContextGetter() {} 323 SystemURLRequestContextGetter::~SystemURLRequestContextGetter() {}
323 324
324 net::URLRequestContext* SystemURLRequestContextGetter::GetURLRequestContext() { 325 net::URLRequestContext* SystemURLRequestContextGetter::GetURLRequestContext() {
325 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 326 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
326 DCHECK(io_thread_->globals()->system_request_context); 327 DCHECK(io_thread_->globals()->system_request_context);
327 328
328 return io_thread_->globals()->system_request_context; 329 return io_thread_->globals()->system_request_context;
329 } 330 }
(...skipping 10 matching lines...) Expand all
340 IOThread::Globals::MediaGlobals::MediaGlobals() {} 341 IOThread::Globals::MediaGlobals::MediaGlobals() {}
341 342
342 IOThread::Globals::MediaGlobals::~MediaGlobals() {} 343 IOThread::Globals::MediaGlobals::~MediaGlobals() {}
343 344
344 // |local_state| is passed in explicitly in order to (1) reduce implicit 345 // |local_state| is passed in explicitly in order to (1) reduce implicit
345 // dependencies and (2) make IOThread more flexible for testing. 346 // dependencies and (2) make IOThread more flexible for testing.
346 IOThread::IOThread( 347 IOThread::IOThread(
347 PrefService* local_state, 348 PrefService* local_state,
348 ChromeNetLog* net_log, 349 ChromeNetLog* net_log,
349 ExtensionEventRouterForwarder* extension_event_router_forwarder) 350 ExtensionEventRouterForwarder* extension_event_router_forwarder)
350 : content::BrowserProcessSubThread(BrowserThread::IO), 351 : net_log_(net_log),
351 net_log_(net_log),
352 extension_event_router_forwarder_(extension_event_router_forwarder), 352 extension_event_router_forwarder_(extension_event_router_forwarder),
353 globals_(NULL), 353 globals_(NULL),
354 sdch_manager_(NULL), 354 sdch_manager_(NULL),
355 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { 355 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
356 // We call RegisterPrefs() here (instead of inside browser_prefs.cc) to make 356 // We call RegisterPrefs() here (instead of inside browser_prefs.cc) to make
357 // sure that everything is initialized in the right order. 357 // sure that everything is initialized in the right order.
358 RegisterPrefs(local_state); 358 RegisterPrefs(local_state);
359 auth_schemes_ = local_state->GetString(prefs::kAuthSchemes); 359 auth_schemes_ = local_state->GetString(prefs::kAuthSchemes);
360 negotiate_disable_cname_lookup_ = local_state->GetBoolean( 360 negotiate_disable_cname_lookup_ = local_state->GetBoolean(
361 prefs::kDisableAuthNegotiateCnameLookup); 361 prefs::kDisableAuthNegotiateCnameLookup);
362 negotiate_enable_port_ = local_state->GetBoolean( 362 negotiate_enable_port_ = local_state->GetBoolean(
363 prefs::kEnableAuthNegotiatePort); 363 prefs::kEnableAuthNegotiatePort);
364 auth_server_whitelist_ = local_state->GetString(prefs::kAuthServerWhitelist); 364 auth_server_whitelist_ = local_state->GetString(prefs::kAuthServerWhitelist);
365 auth_delegate_whitelist_ = local_state->GetString( 365 auth_delegate_whitelist_ = local_state->GetString(
366 prefs::kAuthNegotiateDelegateWhitelist); 366 prefs::kAuthNegotiateDelegateWhitelist);
367 gssapi_library_name_ = local_state->GetString(prefs::kGSSAPILibraryName); 367 gssapi_library_name_ = local_state->GetString(prefs::kGSSAPILibraryName);
368 pref_proxy_config_tracker_.reset( 368 pref_proxy_config_tracker_.reset(
369 ProxyServiceFactory::CreatePrefProxyConfigTracker(local_state)); 369 ProxyServiceFactory::CreatePrefProxyConfigTracker(local_state));
370 ChromeNetworkDelegate::InitializeReferrersEnabled(&system_enable_referrers_, 370 ChromeNetworkDelegate::InitializeReferrersEnabled(&system_enable_referrers_,
371 local_state); 371 local_state);
372 ssl_config_service_manager_.reset( 372 ssl_config_service_manager_.reset(
373 SSLConfigServiceManager::CreateDefaultManager(local_state)); 373 SSLConfigServiceManager::CreateDefaultManager(local_state));
374 MessageLoop::current()->PostTask( 374
375 FROM_HERE, base::Bind(&IOThread::InitSystemRequestContext, 375 BrowserThread::SetDelegate(BrowserThread::IO, this);
376 weak_factory_.GetWeakPtr()));
377 } 376 }
378 377
379 IOThread::~IOThread() { 378 IOThread::~IOThread() {
380 if (pref_proxy_config_tracker_.get()) 379 if (pref_proxy_config_tracker_.get())
381 pref_proxy_config_tracker_->DetachFromPrefService(); 380 pref_proxy_config_tracker_->DetachFromPrefService();
382 // We cannot rely on our base class to stop the thread since we want our
383 // CleanUp function to run.
384 Stop();
385 DCHECK(!globals_); 381 DCHECK(!globals_);
386 } 382 }
387 383
388 IOThread::Globals* IOThread::globals() { 384 IOThread::Globals* IOThread::globals() {
389 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 385 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
390 return globals_; 386 return globals_;
391 } 387 }
392 388
393 ChromeNetLog* IOThread::net_log() { 389 ChromeNetLog* IOThread::net_log() {
394 return net_log_; 390 return net_log_;
395 } 391 }
396 392
397 net::URLRequestContextGetter* IOThread::system_url_request_context_getter() { 393 net::URLRequestContextGetter* IOThread::system_url_request_context_getter() {
398 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 394 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
399 if (!system_url_request_context_getter_) { 395 if (!system_url_request_context_getter_) {
400 InitSystemRequestContext(); 396 InitSystemRequestContext();
401 } 397 }
402 return system_url_request_context_getter_; 398 return system_url_request_context_getter_;
403 } 399 }
404 400
405 void IOThread::Init() { 401 void IOThread::Init() {
406 // Though this thread is called the "IO" thread, it actually just routes 402 // Though this thread is called the "IO" thread, it actually just routes
407 // messages around; it shouldn't be allowed to perform any blocking disk I/O. 403 // messages around; it shouldn't be allowed to perform any blocking disk I/O.
408 base::ThreadRestrictions::SetIOAllowed(false); 404 base::ThreadRestrictions::SetIOAllowed(false);
409 405
410 content::BrowserProcessSubThread::Init(); 406 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
411
412 DCHECK_EQ(MessageLoop::TYPE_IO, message_loop()->type());
413 407
414 #if defined(USE_NSS) 408 #if defined(USE_NSS)
415 net::SetMessageLoopForOCSP(); 409 net::SetMessageLoopForOCSP();
416 #endif // defined(USE_NSS) 410 #endif // defined(USE_NSS)
417 411
418 DCHECK(!globals_); 412 DCHECK(!globals_);
419 globals_ = new Globals; 413 globals_ = new Globals;
420 414
421 globals_->media.media_internals.reset(new MediaInternals()); 415 globals_->media.media_internals.reset(new MediaInternals());
422 416
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 globals_->proxy_script_fetcher_http_transaction_factory.reset( 467 globals_->proxy_script_fetcher_http_transaction_factory.reset(
474 new net::HttpNetworkLayer(network_session)); 468 new net::HttpNetworkLayer(network_session));
475 globals_->proxy_script_fetcher_ftp_transaction_factory.reset( 469 globals_->proxy_script_fetcher_ftp_transaction_factory.reset(
476 new net::FtpNetworkLayer(globals_->host_resolver.get())); 470 new net::FtpNetworkLayer(globals_->host_resolver.get()));
477 471
478 globals_->proxy_script_fetcher_context = 472 globals_->proxy_script_fetcher_context =
479 ConstructProxyScriptFetcherContext(globals_, net_log_); 473 ConstructProxyScriptFetcherContext(globals_, net_log_);
480 474
481 sdch_manager_ = new net::SdchManager(); 475 sdch_manager_ = new net::SdchManager();
482 sdch_manager_->set_sdch_fetcher(new SdchDictionaryFetcher); 476 sdch_manager_->set_sdch_fetcher(new SdchDictionaryFetcher);
477
478 // InitSystemRequestContext turns right around and posts a task back
479 // to the IO thread, so we can't let it run until we know the IO
480 // thread has started.
481 //
482 // Note that since we are at BrowserThread::Init time, the UI thread
483 // is blocked waiting for the thread to start. Therefore, posting
484 // this task to the main thread's message loop here is guaranteed to
485 // get it onto the message loop while the IOThread object still
486 // exists. However, the message might not be processed on the UI
487 // thread until after IOThread is gone, so use a weak pointer.
488 BrowserThread::PostTask(BrowserThread::UI,
489 FROM_HERE,
490 base::Bind(&IOThread::InitSystemRequestContext,
491 weak_factory_.GetWeakPtr()));
492
493 // We constructed the weak pointer on the IO thread but it will be
494 // used on the UI thread. Call this to avoid a thread checker
495 // error.
496 weak_factory_.DetachFromThread();
483 } 497 }
484 498
485 void IOThread::CleanUp() { 499 void IOThread::CleanUp() {
486 delete sdch_manager_; 500 delete sdch_manager_;
487 sdch_manager_ = NULL; 501 sdch_manager_ = NULL;
488 502
489 // Step 1: Kill all things that might be holding onto 503 // Step 1: Kill all things that might be holding onto
490 // net::URLRequest/net::URLRequestContexts. 504 // net::URLRequest/net::URLRequestContexts.
491 505
492 #if defined(USE_NSS) 506 #if defined(USE_NSS)
(...skipping 20 matching lines...) Expand all
513 527
514 system_proxy_config_service_.reset(); 528 system_proxy_config_service_.reset();
515 529
516 delete globals_; 530 delete globals_;
517 globals_ = NULL; 531 globals_ = NULL;
518 532
519 // net::URLRequest instances must NOT outlive the IO thread. 533 // net::URLRequest instances must NOT outlive the IO thread.
520 base::debug::LeakTracker<net::URLRequest>::CheckForLeaks(); 534 base::debug::LeakTracker<net::URLRequest>::CheckForLeaks();
521 535
522 base::debug::LeakTracker<SystemURLRequestContextGetter>::CheckForLeaks(); 536 base::debug::LeakTracker<SystemURLRequestContextGetter>::CheckForLeaks();
523
524 // This will delete the |notification_service_|. Make sure it's done after
525 // anything else can reference it.
526 content::BrowserProcessSubThread::CleanUp();
527 } 537 }
528 538
529 // static 539 // static
530 void IOThread::RegisterPrefs(PrefService* local_state) { 540 void IOThread::RegisterPrefs(PrefService* local_state) {
531 local_state->RegisterStringPref(prefs::kAuthSchemes, 541 local_state->RegisterStringPref(prefs::kAuthSchemes,
532 "basic,digest,ntlm,negotiate"); 542 "basic,digest,ntlm,negotiate");
533 local_state->RegisterBooleanPref(prefs::kDisableAuthNegotiateCnameLookup, 543 local_state->RegisterBooleanPref(prefs::kDisableAuthNegotiateCnameLookup,
534 false); 544 false);
535 local_state->RegisterBooleanPref(prefs::kEnableAuthNegotiatePort, false); 545 local_state->RegisterBooleanPref(prefs::kEnableAuthNegotiatePort, false);
536 local_state->RegisterStringPref(prefs::kAuthServerWhitelist, ""); 546 local_state->RegisterStringPref(prefs::kAuthServerWhitelist, "");
(...skipping 30 matching lines...) Expand all
567 } 577 }
568 578
569 void IOThread::ClearHostCache() { 579 void IOThread::ClearHostCache() {
570 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 580 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
571 581
572 net::HostCache* host_cache = globals_->host_resolver->GetHostCache(); 582 net::HostCache* host_cache = globals_->host_resolver->GetHostCache();
573 if (host_cache) 583 if (host_cache)
574 host_cache->clear(); 584 host_cache->clear();
575 } 585 }
576 586
587 MessageLoop* IOThread::message_loop() const {
588 return BrowserThread::UnsafeGetBrowserThread(
589 BrowserThread::IO)->message_loop();
590 }
591
577 net::SSLConfigService* IOThread::GetSSLConfigService() { 592 net::SSLConfigService* IOThread::GetSSLConfigService() {
578 return ssl_config_service_manager_->Get(); 593 return ssl_config_service_manager_->Get();
579 } 594 }
580 595
581 void IOThread::InitSystemRequestContext() { 596 void IOThread::InitSystemRequestContext() {
582 if (system_url_request_context_getter_) 597 if (system_url_request_context_getter_)
583 return; 598 return;
584 // If we're in unit_tests, IOThread may not be run. 599 // If we're in unit_tests, IOThread may not be run.
585 if (!message_loop()) 600 if (!message_loop())
586 return; 601 return;
587 ChromeProxyConfigService* proxy_config_service = 602 ChromeProxyConfigService* proxy_config_service =
588 ProxyServiceFactory::CreateProxyConfigService(); 603 ProxyServiceFactory::CreateProxyConfigService();
589 system_proxy_config_service_.reset(proxy_config_service); 604 system_proxy_config_service_.reset(proxy_config_service);
590 if (pref_proxy_config_tracker_.get()) { 605 if (pref_proxy_config_tracker_.get()) {
591 pref_proxy_config_tracker_->SetChromeProxyConfigService( 606 pref_proxy_config_tracker_->SetChromeProxyConfigService(
592 proxy_config_service); 607 proxy_config_service);
593 } 608 }
594 system_url_request_context_getter_ = 609 system_url_request_context_getter_ =
595 new SystemURLRequestContextGetter(this); 610 new SystemURLRequestContextGetter(this);
611 // Safe to post an unretained this pointer, since IOThread is
612 // guaranteed to outlive the IO BrowserThread.
596 message_loop()->PostTask( 613 message_loop()->PostTask(
597 FROM_HERE, base::Bind(&IOThread::InitSystemRequestContextOnIOThread, 614 FROM_HERE, base::Bind(&IOThread::InitSystemRequestContextOnIOThread,
598 base::Unretained(this))); 615 base::Unretained(this)));
599 } 616 }
600 617
601 void IOThread::InitSystemRequestContextOnIOThread() { 618 void IOThread::InitSystemRequestContextOnIOThread() {
602 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 619 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
603 DCHECK(!globals_->system_proxy_service.get()); 620 DCHECK(!globals_->system_proxy_service.get());
604 DCHECK(system_proxy_config_service_.get()); 621 DCHECK(system_proxy_config_service_.get());
605 622
(...skipping 20 matching lines...) Expand all
626 system_params.network_delegate = globals_->system_network_delegate.get(); 643 system_params.network_delegate = globals_->system_network_delegate.get();
627 system_params.net_log = net_log_; 644 system_params.net_log = net_log_;
628 globals_->system_http_transaction_factory.reset( 645 globals_->system_http_transaction_factory.reset(
629 new net::HttpNetworkLayer( 646 new net::HttpNetworkLayer(
630 new net::HttpNetworkSession(system_params))); 647 new net::HttpNetworkSession(system_params)));
631 globals_->system_ftp_transaction_factory.reset( 648 globals_->system_ftp_transaction_factory.reset(
632 new net::FtpNetworkLayer(globals_->host_resolver.get())); 649 new net::FtpNetworkLayer(globals_->host_resolver.get()));
633 globals_->system_request_context = 650 globals_->system_request_context =
634 ConstructSystemRequestContext(globals_, net_log_); 651 ConstructSystemRequestContext(globals_, net_log_);
635 } 652 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698