summaryrefslogtreecommitdiffstats
path: root/net/base/host_resolver.cc
diff options
context:
space:
mode:
authorericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-16 20:14:27 +0000
committerericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-16 20:14:27 +0000
commit04a0f0269fc3e37cf6d79b86ca136e45d63a14b5 (patch)
tree68fdeca2da4b79d08a76a68320668852f8f4c4b6 /net/base/host_resolver.cc
parent83f1b0828b19c791df2f4765296777e4bfeb60b2 (diff)
downloadchromium_src-04a0f0269fc3e37cf6d79b86ca136e45d63a14b5.zip
chromium_src-04a0f0269fc3e37cf6d79b86ca136e45d63a14b5.tar.gz
chromium_src-04a0f0269fc3e37cf6d79b86ca136e45d63a14b5.tar.bz2
* Add an OnCancelResolution() notifier to HostResolver::Observer, so observers can tell when a request has been cancelled.
* Use OnCancelResolution() in DNS prefetcher observer, to avoid leaking entries in the |resolution| table when requests are cancelled. (BUG=14138) * Fix a bug where completion notification wasn't being sent when the response was cached. (BUG=14188) BUG=14138,14188 TEST=HostResolverTest.CancellationObserver, HostResolverTest.Observer Review URL: http://codereview.chromium.org/125171 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18520 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/host_resolver.cc')
-rw-r--r--net/base/host_resolver.cc42
1 files changed, 36 insertions, 6 deletions
diff --git a/net/base/host_resolver.cc b/net/base/host_resolver.cc
index 5a357eb..ca742da 100644
--- a/net/base/host_resolver.cc
+++ b/net/base/host_resolver.cc
@@ -184,7 +184,7 @@ class HostResolver::Request {
addresses_(addresses) {}
// Mark the request as cancelled.
- void Cancel() {
+ void MarkAsCancelled() {
job_ = NULL;
callback_ = NULL;
addresses_ = NULL;
@@ -289,10 +289,26 @@ class HostResolver::Job : public base::RefCountedThreadSafe<HostResolver::Job> {
// Cancels the current job. Callable from origin thread.
void Cancel() {
+ HostResolver* resolver = resolver_;
resolver_ = NULL;
- AutoLock locked(origin_loop_lock_);
- origin_loop_ = NULL;
+ // Mark the job as cancelled, so when worker thread completes it will
+ // not try to post completion to origin loop.
+ {
+ AutoLock locked(origin_loop_lock_);
+ origin_loop_ = NULL;
+ }
+
+ // We don't have to do anything further to actually cancel the requests
+ // that were attached to this job (since they are unreachable now).
+ // But we will call HostResolver::CancelRequest(Request*) on each one
+ // in order to notify any observers.
+ for (RequestsList::const_iterator it = requests_.begin();
+ it != requests_.end(); ++it) {
+ HostResolver::Request* req = *it;
+ if (!req->was_cancelled())
+ resolver->CancelRequest(req);
+ }
}
// Called from origin thread.
@@ -390,7 +406,7 @@ HostResolver::HostResolver(int max_cache_entries, int cache_duration_ms)
HostResolver::~HostResolver() {
// Cancel the outstanding jobs. Those jobs may contain several attached
- // requests, which will now never be completed.
+ // requests, which will also be cancelled.
for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ++it)
it->second->Cancel();
@@ -417,7 +433,12 @@ int HostResolver::Resolve(const RequestInfo& info,
info.hostname(), base::TimeTicks::Now());
if (cache_entry) {
addresses->SetFrom(cache_entry->addrlist, info.port());
- return OK;
+ int error = OK;
+
+ // Notify registered observers.
+ NotifyObserversFinishRequest(request_id, info, error);
+
+ return error;
}
}
@@ -478,7 +499,8 @@ void HostResolver::CancelRequest(Request* req) {
DCHECK(req);
DCHECK(req->job());
// NULL out the fields of req, to mark it as cancelled.
- req->Cancel();
+ req->MarkAsCancelled();
+ NotifyObserversCancelRequest(req->id(), req->info());
}
void HostResolver::AddObserver(Observer* observer) {
@@ -569,6 +591,14 @@ void HostResolver::NotifyObserversFinishRequest(int request_id,
}
}
+void HostResolver::NotifyObserversCancelRequest(int request_id,
+ const RequestInfo& info) {
+ for (ObserversList::iterator it = observers_.begin();
+ it != observers_.end(); ++it) {
+ (*it)->OnCancelResolution(request_id, info);
+ }
+}
+
//-----------------------------------------------------------------------------
SingleRequestHostResolver::SingleRequestHostResolver(HostResolver* resolver)