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

Unified Diff: net/base/host_resolver.cc

Issue 125107: * Move the global "DnsResolutionObserver" code depended on by DNS prefetcher,... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Address jar's comments Created 11 years, 6 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/base/host_resolver.h ('k') | net/base/host_resolver_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/base/host_resolver.cc
===================================================================
--- net/base/host_resolver.cc (revision 18360)
+++ net/base/host_resolver.cc (working copy)
@@ -22,6 +22,7 @@
#include "base/time.h"
#include "base/worker_pool.h"
#include "net/base/address_list.h"
+#include "net/base/dns_resolution_observer.h"
#include "net/base/net_errors.h"
#if defined(OS_LINUX)
@@ -178,8 +179,10 @@
class HostResolver::Request {
public:
- Request(CompletionCallback* callback, AddressList* addresses, int port)
- : job_(NULL), callback_(callback), addresses_(addresses), port_(port) {}
+ Request(int id, const RequestInfo& info, CompletionCallback* callback,
+ AddressList* addresses)
+ : id_(id), info_(info), job_(NULL), callback_(callback),
+ addresses_(addresses) {}
// Mark the request as cancelled.
void Cancel() {
@@ -200,19 +203,33 @@
void OnComplete(int error, const AddressList& addrlist) {
if (error == OK)
- addresses_->SetFrom(addrlist, port_);
+ addresses_->SetFrom(addrlist, port());
callback_->Run(error);
}
int port() const {
- return port_;
+ return info_.port();
}
Job* job() const {
return job_;
}
+ int id() const {
+ return id_;
+ }
+
+ const RequestInfo& info() const {
+ return info_;
+ }
+
private:
+ // Unique ID for this request. Used by observers to identify requests.
+ int id_;
+
+ // The request info that started the request.
+ RequestInfo info_;
+
// The resolve job (running in worker pool) that this request is dependent on.
Job* job_;
@@ -222,9 +239,6 @@
// The address list to save result into.
AddressList* addresses_;
- // The desired port number for the socket addresses.
- int port_;
-
DISALLOW_COPY_AND_ASSIGN(Request);
};
@@ -369,7 +383,7 @@
//-----------------------------------------------------------------------------
HostResolver::HostResolver(int max_cache_entries, int cache_duration_ms)
- : cache_(max_cache_entries, cache_duration_ms) {
+ : cache_(max_cache_entries, cache_duration_ms), next_request_id_(0) {
#if defined(OS_WIN)
EnsureWinsockInit();
#endif
@@ -388,40 +402,51 @@
// TODO(eroman): Don't create cache entries for hostnames which are simply IP
// address literals.
-int HostResolver::Resolve(const std::string& hostname, int port,
+int HostResolver::Resolve(const RequestInfo& info,
AddressList* addresses,
CompletionCallback* callback,
Request** out_req) {
+ // Choose a unique ID number for observers to see.
+ int request_id = next_request_id_++;
+
+ // Notify registered observers.
+ NotifyObserversStartRequest(request_id, info);
+
// If we have an unexpired cache entry, use it.
- const HostCache::Entry* cache_entry = cache_.Lookup(
- hostname, base::TimeTicks::Now());
- if (cache_entry) {
- addresses->SetFrom(cache_entry->addrlist, port);
- return OK;
+ if (info.allow_cached_response()) {
+ const HostCache::Entry* cache_entry = cache_.Lookup(
+ info.hostname(), base::TimeTicks::Now());
+ if (cache_entry) {
+ addresses->SetFrom(cache_entry->addrlist, info.port());
+ return OK;
+ }
}
// If no callback was specified, do a synchronous resolution.
if (!callback) {
struct addrinfo* results;
- int error = ResolveAddrInfo(host_mapper, hostname, &results);
+ int error = ResolveAddrInfo(host_mapper, info.hostname(), &results);
// Adopt the address list.
AddressList addrlist;
if (error == OK) {
addrlist.Adopt(results);
- addrlist.SetPort(port);
+ addrlist.SetPort(info.port());
*addresses = addrlist;
}
// Write to cache.
- cache_.Set(hostname, error, addrlist, base::TimeTicks::Now());
+ cache_.Set(info.hostname(), error, addrlist, base::TimeTicks::Now());
+ // Notify registered observers.
+ NotifyObserversFinishRequest(request_id, info, error);
+
return error;
}
// Create a handle for this request, and pass it back to the user if they
// asked for it (out_req != NULL).
- Request* req = new Request(callback, addresses, port);
+ Request* req = new Request(request_id, info, callback, addresses);
if (out_req)
*out_req = req;
@@ -429,14 +454,14 @@
// calling "getaddrinfo(hostname)" on a worker thread.
scoped_refptr<Job> job;
- // If there is already an outstanding job to resolve |hostname|, use it.
- // This prevents starting concurrent resolves for the same hostname.
- job = FindOutstandingJob(hostname);
+ // If there is already an outstanding job to resolve |info.hostname()|, use
+ // it. This prevents starting concurrent resolves for the same hostname.
+ job = FindOutstandingJob(info.hostname());
if (job) {
job->AddRequest(req);
} else {
// Create a new job for this request.
- job = new Job(this, hostname);
+ job = new Job(this, info.hostname());
job->AddRequest(req);
AddOutstandingJob(job);
// TODO(eroman): Bound the total number of concurrent jobs.
@@ -457,6 +482,20 @@
req->Cancel();
}
+void HostResolver::AddObserver(DnsResolutionObserver* observer) {
+ observers_.push_back(observer);
+}
+
+void HostResolver::RemoveObserver(DnsResolutionObserver* observer) {
+ ObserversList::iterator it =
+ std::find(observers_.begin(), observers_.end(), observer);
+
+ // Observer must exist.
+ DCHECK(it != observers_.end());
+
+ observers_.erase(it);
+}
+
void HostResolver::AddOutstandingJob(Job* job) {
scoped_refptr<Job>& found_job = jobs_[job->host()];
DCHECK(!found_job);
@@ -497,6 +536,10 @@
Request* req = *it;
if (!req->was_cancelled()) {
DCHECK_EQ(job, req->job());
+
+ // Notify registered observers.
+ NotifyObserversFinishRequest(req->id(), req->info(), error);
+
req->OnComplete(error, addrlist);
// Check if the job was cancelled as a result of running the callback.
@@ -509,6 +552,24 @@
cur_completing_job_ = NULL;
}
+void HostResolver::NotifyObserversStartRequest(int request_id,
+ const RequestInfo& info) {
+ for (ObserversList::iterator it = observers_.begin();
+ it != observers_.end(); ++it) {
+ (*it)->OnStartResolution(request_id, info);
+ }
+}
+
+void HostResolver::NotifyObserversFinishRequest(int request_id,
+ const RequestInfo& info,
+ int error) {
+ bool was_resolved = error == OK;
+ for (ObserversList::iterator it = observers_.begin();
+ it != observers_.end(); ++it) {
+ (*it)->OnFinishResolutionWithStatus(request_id, was_resolved, info);
+ }
+}
+
//-----------------------------------------------------------------------------
SingleRequestHostResolver::SingleRequestHostResolver(HostResolver* resolver)
@@ -526,10 +587,9 @@
}
}
-int SingleRequestHostResolver::Resolve(
- const std::string& hostname, int port,
- AddressList* addresses,
- CompletionCallback* callback) {
+int SingleRequestHostResolver::Resolve(const HostResolver::RequestInfo& info,
+ AddressList* addresses,
+ CompletionCallback* callback) {
DCHECK(!cur_request_ && !cur_request_callback_) << "resolver already in use";
HostResolver::Request* request = NULL;
@@ -538,8 +598,7 @@
// we can clear out |cur_request_*|.
CompletionCallback* transient_callback = callback ? &callback_ : NULL;
- int rv = resolver_->Resolve(
- hostname, port, addresses, transient_callback, &request);
+ int rv = resolver_->Resolve(info, addresses, transient_callback, &request);
if (rv == ERR_IO_PENDING) {
// Cleared in OnResolveCompletion().
« no previous file with comments | « net/base/host_resolver.h ('k') | net/base/host_resolver_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698