summaryrefslogtreecommitdiffstats
path: root/chrome/browser/io_thread.cc
diff options
context:
space:
mode:
authorwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-22 22:24:46 +0000
committerwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-22 22:24:46 +0000
commit562d71ef0d9bb578482240982a1f61a94f9f2e29 (patch)
treee89dc9552fbea182627ab4c6654962be6037df13 /chrome/browser/io_thread.cc
parentf7e7babb6098aea4f6fb2b458a79d8f31c68b526 (diff)
downloadchromium_src-562d71ef0d9bb578482240982a1f61a94f9f2e29.zip
chromium_src-562d71ef0d9bb578482240982a1f61a94f9f2e29.tar.gz
chromium_src-562d71ef0d9bb578482240982a1f61a94f9f2e29.tar.bz2
Release ChromeURLRequestContextGetters' references on IO thread shutdown.
We register all ChromeURLRequestContextGetters that have a reference to a ChromeURLRequestContext with the IOThread. We unregister them when they go away. In IOThread::CleanUp(), we tell the known ChromeURLRequestContextGetters to release their references to ChromeURLRequestContexts. BUG=58859 TEST=none Review URL: http://codereview.chromium.org/3686003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@63578 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/io_thread.cc')
-rw-r--r--chrome/browser/io_thread.cc61
1 files changed, 52 insertions, 9 deletions
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 990f9a4..4dc520a 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -16,6 +16,7 @@
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/gpu_process_host.h"
#include "chrome/browser/net/chrome_net_log.h"
+#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/net/connect_interceptor.h"
#include "chrome/browser/net/passive_log_collector.h"
#include "chrome/browser/net/predictor_api.h"
@@ -217,6 +218,30 @@ void IOThread::InitNetworkPredictor(
startup_urls, referral_list, preconnect_enabled));
}
+void IOThread::RegisterURLRequestContextGetter(
+ ChromeURLRequestContextGetter* url_request_context_getter) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ std::list<ChromeURLRequestContextGetter*>::const_iterator it =
+ std::find(url_request_context_getters_.begin(),
+ url_request_context_getters_.end(),
+ url_request_context_getter);
+ DCHECK(it == url_request_context_getters_.end());
+ url_request_context_getters_.push_back(url_request_context_getter);
+}
+
+void IOThread::UnregisterURLRequestContextGetter(
+ ChromeURLRequestContextGetter* url_request_context_getter) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ std::list<ChromeURLRequestContextGetter*>::iterator it =
+ std::find(url_request_context_getters_.begin(),
+ url_request_context_getters_.end(),
+ url_request_context_getter);
+ DCHECK(it != url_request_context_getters_.end());
+ // This does not scale, but we shouldn't have many URLRequestContextGetters in
+ // the first place, so this should be fine.
+ url_request_context_getters_.erase(it);
+}
+
void IOThread::ChangedToOnTheRecord() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
message_loop()->PostTask(
@@ -259,6 +284,9 @@ void IOThread::Init() {
}
void IOThread::CleanUp() {
+ // Step 1: Kill all things that might be holding onto
+ // URLRequest/URLRequestContexts.
+
#if defined(USE_NSS)
net::ShutdownOCSP();
#endif // defined(USE_NSS)
@@ -266,14 +294,32 @@ void IOThread::CleanUp() {
// Destroy all URLRequests started by URLFetchers.
URLFetcher::CancelAll();
- // This must be reset before the ChromeNetLog is destroyed.
- network_change_observer_.reset();
+ // Break any cycles between the ProxyScriptFetcher and URLRequestContext.
+ for (ProxyScriptFetchers::const_iterator it = fetchers_.begin();
+ it != fetchers_.end(); ++it) {
+ (*it)->Cancel();
+ }
// If any child processes are still running, terminate them and
// and delete the BrowserChildProcessHost instances to release whatever
// IO thread only resources they are referencing.
BrowserChildProcessHost::TerminateAll();
+ std::list<ChromeURLRequestContextGetter*> url_request_context_getters;
+ url_request_context_getters.swap(url_request_context_getters_);
+ for (std::list<ChromeURLRequestContextGetter*>::iterator it =
+ url_request_context_getters.begin();
+ it != url_request_context_getters.end(); ++it) {
+ ChromeURLRequestContextGetter* getter = *it;
+ getter->ReleaseURLRequestContext();
+ }
+
+ // Step 2: Release objects that the URLRequestContext could have been pointing
+ // to.
+
+ // This must be reset before the ChromeNetLog is destroyed.
+ network_change_observer_.reset();
+
// Not initialized in Init(). May not be initialized.
if (predictor_) {
predictor_->Shutdown();
@@ -294,12 +340,6 @@ void IOThread::CleanUp() {
globals_->host_resolver.get()->GetAsHostResolverImpl()->Shutdown();
}
- // Break any cycles between the ProxyScriptFetcher and URLRequestContext.
- for (ProxyScriptFetchers::const_iterator it = fetchers_.begin();
- it != fetchers_.end(); ++it) {
- (*it)->Cancel();
- }
-
// We will delete the NetLog as part of CleanUpAfterMessageLoopDestruction()
// in case any of the message loop destruction observers try to access it.
deferred_net_log_to_delete_.reset(globals_->net_log.release());
@@ -312,10 +352,13 @@ void IOThread::CleanUp() {
void IOThread::CleanUpAfterMessageLoopDestruction() {
// TODO(eroman): get rid of this special case for 39723. If we could instead
- // have a method that runs after the message loop destruction obsevers have
+ // have a method that runs after the message loop destruction observers have
// run, but before the message loop itself is destroyed, we could safely
// combine the two cleanups.
deferred_net_log_to_delete_.reset();
+
+ // This will delete the |notification_service_|. Make sure it's done after
+ // anything else can reference it.
BrowserProcessSubThread::CleanUpAfterMessageLoopDestruction();
// URLRequest instances must NOT outlive the IO thread.