Index: net/base/host_resolver_impl.cc |
=================================================================== |
--- net/base/host_resolver_impl.cc (revision 57182) |
+++ net/base/host_resolver_impl.cc (working copy) |
@@ -27,9 +27,11 @@ |
#include "base/values.h" |
#include "base/worker_pool.h" |
#include "net/base/address_list.h" |
+#include "net/base/address_list_net_log_param.h" |
+#include "net/base/host_port_pair.h" |
#include "net/base/host_resolver_proc.h" |
+#include "net/base/net_errors.h" |
#include "net/base/net_log.h" |
-#include "net/base/net_errors.h" |
#include "net/base/net_util.h" |
#if defined(OS_WIN) |
@@ -53,7 +55,8 @@ |
} // anonymous namespace |
-HostResolver* CreateSystemHostResolver(size_t max_concurrent_resolves) { |
+HostResolver* CreateSystemHostResolver(size_t max_concurrent_resolves, |
+ NetLog* net_log) { |
// Maximum of 50 concurrent threads. |
// TODO(eroman): Adjust this, do some A/B experiments. |
static const size_t kDefaultMaxJobs = 50u; |
@@ -63,7 +66,7 @@ |
HostResolverImpl* resolver = |
new HostResolverImpl(NULL, CreateDefaultCache(), |
- max_concurrent_resolves); |
+ max_concurrent_resolves, net_log); |
return resolver; |
} |
@@ -88,16 +91,14 @@ |
// Extra parameters to attach to the NetLog when the resolve failed. |
class HostResolveFailedParams : public NetLog::EventParameters { |
public: |
- HostResolveFailedParams(int net_error, int os_error, bool was_from_cache) |
+ HostResolveFailedParams(int net_error, int os_error) |
: net_error_(net_error), |
- os_error_(os_error), |
- was_from_cache_(was_from_cache) { |
+ os_error_(os_error) { |
} |
virtual Value* ToValue() const { |
DictionaryValue* dict = new DictionaryValue(); |
dict->SetInteger("net_error", net_error_); |
- dict->SetBoolean("was_from_cache", was_from_cache_); |
if (os_error_) { |
dict->SetInteger("os_error", os_error_); |
@@ -125,9 +126,55 @@ |
private: |
const int net_error_; |
const int os_error_; |
- const bool was_from_cache_; |
}; |
+// Parameters representing the information in a RequestInfo object, along with |
+// the associated NetLog::Source. |
+class RequestInfoParameters : public NetLog::EventParameters { |
+ public: |
+ RequestInfoParameters(const HostResolver::RequestInfo& info, |
+ const NetLog::Source& source) |
+ : info_(info), source_(source) {} |
+ |
+ virtual Value* ToValue() const { |
+ DictionaryValue* dict = new DictionaryValue(); |
+ dict->SetString("host", HostPortPair(info_.hostname(), |
+ info_.port()).ToString()); |
+ dict->SetInteger("address_family", |
+ static_cast<int>(info_.address_family())); |
+ dict->SetBoolean("allow_cached_response", info_.allow_cached_response()); |
+ dict->SetBoolean("is_speculative", info_.is_speculative()); |
+ dict->SetInteger("priority", info_.priority()); |
+ |
+ if (source_.is_valid()) |
+ dict->Set("source_dependency", source_.ToValue()); |
+ |
+ return dict; |
+ } |
+ |
+ private: |
+ const HostResolver::RequestInfo info_; |
+ const NetLog::Source source_; |
+}; |
+ |
+// Parameters associated with the creation of a HostResolveImpl::Job. |
+class JobCreationParameters : public NetLog::EventParameters { |
+ public: |
+ JobCreationParameters(const std::string& host, const NetLog::Source& source) |
+ : host_(host), source_(source) {} |
+ |
+ virtual Value* ToValue() const { |
+ DictionaryValue* dict = new DictionaryValue(); |
+ dict->SetString("host", host_); |
+ dict->Set("source_dependency", source_.ToValue()); |
+ return dict; |
+ } |
+ |
+ private: |
+ const std::string host_; |
+ const NetLog::Source source_; |
+}; |
+ |
// Gets a list of the likely error codes that getaddrinfo() can return |
// (non-exhaustive). These are the error codes that we will track via |
// a histogram. |
@@ -176,12 +223,14 @@ |
class HostResolverImpl::Request { |
public: |
- Request(const BoundNetLog& net_log, |
+ Request(const BoundNetLog& source_net_log, |
+ const BoundNetLog& request_net_log, |
int id, |
const RequestInfo& info, |
CompletionCallback* callback, |
AddressList* addresses) |
- : net_log_(net_log), |
+ : source_net_log_(source_net_log), |
+ request_net_log_(request_net_log), |
id_(id), |
info_(info), |
job_(NULL), |
@@ -220,10 +269,14 @@ |
return job_; |
} |
- const BoundNetLog& net_log() { |
- return net_log_; |
+ const BoundNetLog& source_net_log() { |
+ return source_net_log_; |
} |
+ const BoundNetLog& request_net_log() { |
+ return request_net_log_; |
+ } |
+ |
int id() const { |
return id_; |
} |
@@ -233,7 +286,8 @@ |
} |
private: |
- BoundNetLog net_log_; |
+ BoundNetLog source_net_log_; |
+ BoundNetLog request_net_log_; |
// Unique ID for this request. Used by observers to identify requests. |
int id_; |
@@ -260,20 +314,33 @@ |
class HostResolverImpl::Job |
: public base::RefCountedThreadSafe<HostResolverImpl::Job> { |
public: |
- Job(int id, HostResolverImpl* resolver, const Key& key) |
- : id_(id), |
- key_(key), |
- resolver_(resolver), |
- origin_loop_(MessageLoop::current()), |
- resolver_proc_(resolver->effective_resolver_proc()), |
- error_(OK), |
- os_error_(0), |
- had_non_speculative_request_(false) { |
+ Job(int id, |
+ HostResolverImpl* resolver, |
+ const Key& key, |
+ const BoundNetLog& source_net_log, |
+ NetLog* net_log) |
+ : id_(id), |
+ key_(key), |
+ resolver_(resolver), |
+ origin_loop_(MessageLoop::current()), |
+ resolver_proc_(resolver->effective_resolver_proc()), |
+ error_(OK), |
+ os_error_(0), |
+ had_non_speculative_request_(false), |
+ net_log_(BoundNetLog::Make(net_log, |
+ NetLog::SOURCE_HOST_RESOLVER_IMPL_JOB)) { |
+ net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, |
+ new JobCreationParameters(key.hostname, |
+ source_net_log.source())); |
} |
// Attaches a request to this job. The job takes ownership of |req| and will |
// take care to delete it. |
void AddRequest(Request* req) { |
+ req->request_net_log().BeginEvent( |
+ NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_ATTACH, |
+ new NetLogSourceParameter("source_dependency", net_log_.source())); |
+ |
req->set_job(this); |
requests_.push_back(req); |
@@ -301,6 +368,8 @@ |
// Cancels the current job. Callable from origin thread. |
void Cancel() { |
+ net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL); |
+ |
HostResolver* resolver = resolver_; |
resolver_ = NULL; |
@@ -311,6 +380,10 @@ |
origin_loop_ = NULL; |
} |
+ // End here to prevent issues when a Job outlives the HostResolver that |
+ // spawned it. |
+ net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, NULL); |
+ |
// We will call HostResolverImpl::CancelRequest(Request*) on each one |
// in order to notify any observers. |
for (RequestsList::const_iterator it = requests_.begin(); |
@@ -412,6 +485,17 @@ |
if (was_cancelled()) |
return; |
+ scoped_refptr<NetLog::EventParameters> params; |
+ if (error_ != OK) { |
+ params = new HostResolveFailedParams(error_, os_error_); |
+ } else { |
+ params = new AddressListNetLogParam(results_); |
+ } |
+ |
+ // End here to prevent issues when a Job outlives the HostResolver that |
+ // spawned it. |
+ net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, params); |
+ |
DCHECK(!requests_.empty()); |
// Use the port number of the first request. |
@@ -456,6 +540,8 @@ |
// The time when the job was started. |
base::TimeTicks start_time_; |
+ BoundNetLog net_log_; |
+ |
DISALLOW_COPY_AND_ASSIGN(Job); |
}; |
@@ -608,6 +694,10 @@ |
// evicted from the queue, and returned. Otherwise returns NULL. The caller |
// is responsible for freeing the evicted request. |
Request* InsertPendingRequest(Request* req) { |
+ req->request_net_log().BeginEvent( |
+ NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_POOL_QUEUE, |
+ NULL); |
+ |
PendingRequestsQueue& q = pending_requests_[req->info().priority()]; |
q.push_back(req); |
@@ -620,6 +710,10 @@ |
if (!q.empty()) { |
Request* req = q.front(); |
q.pop_front(); |
+ req->request_net_log().AddEvent( |
+ NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_POOL_QUEUE_EVICTED, NULL); |
+ req->request_net_log().EndEvent( |
+ NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_POOL_QUEUE, NULL); |
return req; |
} |
} |
@@ -635,6 +729,8 @@ |
PendingRequestsQueue::iterator it = std::find(q.begin(), q.end(), req); |
DCHECK(it != q.end()); |
q.erase(it); |
+ req->request_net_log().EndEvent( |
+ NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_POOL_QUEUE, NULL); |
} |
// Removes and returns the highest priority pending request. |
@@ -646,6 +742,8 @@ |
if (!q.empty()) { |
Request* req = q.front(); |
q.pop_front(); |
+ req->request_net_log().EndEvent( |
+ NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_POOL_QUEUE, NULL); |
return req; |
} |
} |
@@ -709,7 +807,8 @@ |
HostResolverImpl::HostResolverImpl( |
HostResolverProc* resolver_proc, |
HostCache* cache, |
- size_t max_jobs) |
+ size_t max_jobs, |
+ NetLog* net_log) |
: cache_(cache), |
max_jobs_(max_jobs), |
next_request_id_(0), |
@@ -718,7 +817,8 @@ |
default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), |
shutdown_(false), |
ipv6_probe_monitoring_(false), |
- additional_resolver_flags_(0) { |
+ additional_resolver_flags_(0), |
+ net_log_(net_log) { |
DCHECK_GT(max_jobs, 0u); |
// It is cumbersome to expose all of the constraints in the constructor, |
@@ -758,7 +858,7 @@ |
AddressList* addresses, |
CompletionCallback* callback, |
RequestHandle* out_req, |
- const BoundNetLog& net_log) { |
+ const BoundNetLog& source_net_log) { |
DCHECK(CalledOnValidThread()); |
if (shutdown_) |
@@ -767,8 +867,12 @@ |
// Choose a unique ID number for observers to see. |
int request_id = next_request_id_++; |
+ // Make a log item for the request. |
+ BoundNetLog request_net_log = BoundNetLog::Make(net_log_, |
+ NetLog::SOURCE_HOST_RESOLVER_IMPL_REQUEST); |
+ |
// Update the net log and notify registered observers. |
- OnStartRequest(net_log, request_id, info); |
+ OnStartRequest(source_net_log, request_net_log, request_id, info); |
// Check for IP literal. |
IPAddressNumber ip_number; |
@@ -781,9 +885,8 @@ |
*addresses = result; |
// Update the net log and notify registered observers. |
- OnFinishRequest(net_log, request_id, info, OK, |
- 0, /* os_error (unknown since from cache) */ |
- false /* was_from_cache */); |
+ OnFinishRequest(source_net_log, request_net_log, request_id, info, OK, |
+ 0 /* os_error (unknown since from cache) */); |
return OK; |
} |
@@ -796,14 +899,15 @@ |
const HostCache::Entry* cache_entry = cache_->Lookup( |
key, base::TimeTicks::Now()); |
if (cache_entry) { |
+ request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT, NULL); |
int net_error = cache_entry->error; |
if (net_error == OK) |
addresses->SetFrom(cache_entry->addrlist, info.port()); |
// Update the net log and notify registered observers. |
- OnFinishRequest(net_log, request_id, info, net_error, |
- 0, /* os_error (unknown since from cache) */ |
- true /* was_from_cache */); |
+ OnFinishRequest(source_net_log, request_net_log, request_id, info, |
+ net_error, |
+ 0 /* os_error (unknown since from cache) */); |
return net_error; |
} |
@@ -826,15 +930,16 @@ |
cache_->Set(key, error, addrlist, base::TimeTicks::Now()); |
// Update the net log and notify registered observers. |
- OnFinishRequest(net_log, request_id, info, error, os_error, |
- false /* was_from_cache */); |
+ OnFinishRequest(source_net_log, request_net_log, request_id, info, error, |
+ os_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(net_log, request_id, info, callback, addresses); |
+ Request* req = new Request(source_net_log, request_net_log, request_id, info, |
+ callback, addresses); |
if (out_req) |
*out_req = reinterpret_cast<RequestHandle>(req); |
@@ -885,11 +990,15 @@ |
JobPool* pool = GetPoolForRequest(req); |
pool->RemovePendingRequest(req); |
request_deleter.reset(req); |
+ } else { |
+ req->request_net_log().EndEvent( |
+ NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_ATTACH, NULL); |
} |
// NULL out the fields of req, to mark it as cancelled. |
req->MarkAsCancelled(); |
- OnCancelRequest(req->net_log(), req->id(), req->info()); |
+ OnCancelRequest(req->source_net_log(), req->request_net_log(), req->id(), |
+ req->info()); |
} |
void HostResolverImpl::AddObserver(HostResolver::Observer* observer) { |
@@ -995,10 +1104,12 @@ |
Request* req = *it; |
if (!req->was_cancelled()) { |
DCHECK_EQ(job, req->job()); |
+ req->request_net_log().EndEvent( |
+ NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_ATTACH, NULL); |
// Update the net log and notify registered observers. |
- OnFinishRequest(req->net_log(), req->id(), req->info(), net_error, |
- os_error, false /* was_from_cache */); |
+ OnFinishRequest(req->source_net_log(), req->request_net_log(), req->id(), |
+ req->info(), net_error, os_error); |
req->OnComplete(net_error, addrlist); |
@@ -1012,11 +1123,18 @@ |
cur_completing_job_ = NULL; |
} |
-void HostResolverImpl::OnStartRequest(const BoundNetLog& net_log, |
+void HostResolverImpl::OnStartRequest(const BoundNetLog& source_net_log, |
+ const BoundNetLog& request_net_log, |
int request_id, |
const RequestInfo& info) { |
- net_log.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, NULL); |
+ source_net_log.BeginEvent( |
+ NetLog::TYPE_HOST_RESOLVER_IMPL, |
+ new NetLogSourceParameter("source_dependency", request_net_log.source())); |
+ request_net_log.BeginEvent( |
+ NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, |
+ new RequestInfoParameters(info, source_net_log.source())); |
+ |
// Notify the observers of the start. |
if (!observers_.empty()) { |
for (ObserversList::iterator it = observers_.begin(); |
@@ -1026,12 +1144,12 @@ |
} |
} |
-void HostResolverImpl::OnFinishRequest(const BoundNetLog& net_log, |
+void HostResolverImpl::OnFinishRequest(const BoundNetLog& source_net_log, |
+ const BoundNetLog& request_net_log, |
int request_id, |
const RequestInfo& info, |
int net_error, |
- int os_error, |
- bool was_from_cache) { |
+ int os_error) { |
bool was_resolved = net_error == OK; |
// Notify the observers of the completion. |
@@ -1042,18 +1160,21 @@ |
} |
} |
- // Log some extra parameters on failure. |
+ // Log some extra parameters on failure for synchronous requests. |
scoped_refptr<NetLog::EventParameters> params; |
- if (!was_resolved) |
- params = new HostResolveFailedParams(net_error, os_error, was_from_cache); |
+ if (!was_resolved) { |
+ params = new HostResolveFailedParams(net_error, os_error); |
+ } |
- net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, params); |
+ request_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, params); |
+ source_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, NULL); |
} |
-void HostResolverImpl::OnCancelRequest(const BoundNetLog& net_log, |
+void HostResolverImpl::OnCancelRequest(const BoundNetLog& source_net_log, |
+ const BoundNetLog& request_net_log, |
int request_id, |
const RequestInfo& info) { |
- net_log.AddEvent(NetLog::TYPE_CANCELLED, NULL); |
+ request_net_log.AddEvent(NetLog::TYPE_CANCELLED, NULL); |
// Notify the observers of the cancellation. |
if (!observers_.empty()) { |
@@ -1063,7 +1184,8 @@ |
} |
} |
- net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, NULL); |
+ request_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, NULL); |
+ source_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, NULL); |
} |
void HostResolverImpl::OnIPAddressChanged() { |
@@ -1160,10 +1282,16 @@ |
HostResolverImpl::Job* HostResolverImpl::CreateAndStartJob(Request* req) { |
DCHECK(CanCreateJobForPool(*GetPoolForRequest(req))); |
Key key = GetEffectiveKeyForRequest(req->info()); |
- scoped_refptr<Job> job = new Job(next_job_id_++, this, key); |
+ |
+ req->request_net_log().AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CREATE_JOB, |
+ NULL); |
+ |
+ scoped_refptr<Job> job = new Job(next_job_id_++, this, key, |
+ req->request_net_log(), net_log_); |
job->AddRequest(req); |
AddOutstandingJob(job); |
job->Start(); |
+ |
return job.get(); |
} |
@@ -1176,9 +1304,9 @@ |
Request* r = req_evicted_from_queue.get(); |
int error = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE; |
- OnFinishRequest(r->net_log(), r->id(), r->info(), error, |
- 0, /* os_error (not applicable) */ |
- false /* was_from_cache */); |
+ OnFinishRequest(r->source_net_log(), r->request_net_log(), r->id(), |
+ r->info(), error, |
+ 0 /* os_error (not applicable) */); |
if (r == req) |
return error; |