summaryrefslogtreecommitdiffstats
path: root/net/base
diff options
context:
space:
mode:
Diffstat (limited to 'net/base')
-rw-r--r--net/base/fixed_host_resolver.h1
-rw-r--r--net/base/host_resolver.h9
-rw-r--r--net/base/host_resolver_impl.cc142
-rw-r--r--net/base/host_resolver_impl.h24
-rw-r--r--net/base/mock_host_resolver.cc4
-rw-r--r--net/base/mock_host_resolver.h1
6 files changed, 163 insertions, 18 deletions
diff --git a/net/base/fixed_host_resolver.h b/net/base/fixed_host_resolver.h
index 92ffeee..b5e4a72 100644
--- a/net/base/fixed_host_resolver.h
+++ b/net/base/fixed_host_resolver.h
@@ -28,7 +28,6 @@ class FixedHostResolver : public HostResolver {
virtual void CancelRequest(RequestHandle req) {}
virtual void AddObserver(Observer* observer) {}
virtual void RemoveObserver(Observer* observer) {}
- virtual HostCache* GetHostCache() { return NULL; }
virtual void Shutdown() {}
private:
diff --git a/net/base/host_resolver.h b/net/base/host_resolver.h
index 0bcbbe8..6ce3c67 100644
--- a/net/base/host_resolver.h
+++ b/net/base/host_resolver.h
@@ -147,10 +147,6 @@ class HostResolver : public base::RefCountedThreadSafe<HostResolver> {
// Unregisters an observer previously added by AddObserver().
virtual void RemoveObserver(Observer* observer) = 0;
- // Returns the host cache, or NULL if this implementation does not use
- // a HostCache.
- virtual HostCache* GetHostCache() = 0;
-
// TODO(eroman): temp hack for http://crbug.com/18373
virtual void Shutdown() = 0;
@@ -160,6 +156,11 @@ class HostResolver : public base::RefCountedThreadSafe<HostResolver> {
// AF_INET6 by passing in ADDRESS_FAMILY_IPV6.
virtual void SetDefaultAddressFamily(AddressFamily address_family) {}
+ // Returns true if this HostResolver is an instance of HostResolverImpl.
+ // Used primarily to expose additional functionality on the
+ // about:net-internals page.
+ virtual bool IsHostResolverImpl() { return false; }
+
protected:
friend class base::RefCountedThreadSafe<HostResolver>;
diff --git a/net/base/host_resolver_impl.cc b/net/base/host_resolver_impl.cc
index b81b4cb..b654ad3 100644
--- a/net/base/host_resolver_impl.cc
+++ b/net/base/host_resolver_impl.cc
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/debug_util.h"
+#include "base/lock.h"
#include "base/message_loop.h"
#include "base/stl_util-inl.h"
#include "base/string_util.h"
@@ -150,28 +151,72 @@ class HostResolverImpl::Request {
//-----------------------------------------------------------------------------
+// Threadsafe log.
+class HostResolverImpl::RequestsTrace
+ : public base::RefCountedThreadSafe<HostResolverImpl::RequestsTrace> {
+ public:
+ RequestsTrace() : log_(new LoadLog(LoadLog::kUnbounded)) {}
+
+ void Add(const std::string& msg) {
+ AutoLock l(lock_);
+ LoadLog::AddString(log_, msg);
+ }
+
+ void Get(LoadLog* out) {
+ AutoLock l(lock_);
+ out->Append(log_);
+ }
+
+ void Clear() {
+ AutoLock l(lock_);
+ log_ = new LoadLog(LoadLog::kUnbounded);
+ }
+
+ private:
+ Lock lock_;
+ scoped_refptr<LoadLog> log_;
+};
+
+//-----------------------------------------------------------------------------
+
// This class represents a request to the worker pool for a "getaddrinfo()"
// call.
class HostResolverImpl::Job
: public base::RefCountedThreadSafe<HostResolverImpl::Job> {
public:
- Job(HostResolverImpl* resolver, const Key& key)
- : key_(key),
+ Job(int id, HostResolverImpl* resolver, const Key& key,
+ RequestsTrace* requests_trace)
+ : id_(id), key_(key),
resolver_(resolver),
origin_loop_(MessageLoop::current()),
resolver_proc_(resolver->effective_resolver_proc()),
+ requests_trace_(requests_trace),
error_(OK) {
+ if (requests_trace_) {
+ requests_trace_->Add(StringPrintf(
+ "Created job j%d for {hostname='%s', address_family=%d}",
+ id_, key.hostname.c_str(),
+ static_cast<int>(key.address_family)));
+ }
}
// Attaches a request to this job. The job takes ownership of |req| and will
// take care to delete it.
void AddRequest(Request* req) {
+ if (requests_trace_) {
+ requests_trace_->Add(StringPrintf(
+ "Attached request r%d to job j%d", req->id(), id_));
+ }
+
req->set_job(this);
requests_.push_back(req);
}
// Called from origin loop.
void Start() {
+ if (requests_trace_)
+ requests_trace_->Add(StringPrintf("Starting job j%d", id_));
+
// Dispatch the job to a worker thread.
if (!WorkerPool::PostTask(FROM_HERE,
NewRunnableMethod(this, &Job::DoLookup), true)) {
@@ -191,6 +236,9 @@ class HostResolverImpl::Job
HostResolver* resolver = resolver_;
resolver_ = NULL;
+ if (requests_trace_)
+ requests_trace_->Add(StringPrintf("Cancelled job j%d", id_));
+
// Mark the job as cancelled, so when worker thread completes it will
// not try to post completion to origin loop.
{
@@ -239,12 +287,22 @@ class HostResolverImpl::Job
}
void DoLookup() {
+ if (requests_trace_) {
+ requests_trace_->Add(StringPrintf(
+ "[resolver thread] Running job j%d", id_));
+ }
+
// Running on the worker thread
error_ = ResolveAddrInfo(resolver_proc_,
key_.hostname,
key_.address_family,
&results_);
+ if (requests_trace_) {
+ requests_trace_->Add(StringPrintf(
+ "[resolver thread] Completed job j%d", id_));
+ }
+
Task* reply = NewRunnableMethod(this, &Job::OnLookupComplete);
// The origin loop could go away while we are trying to post to it, so we
@@ -269,6 +327,9 @@ class HostResolverImpl::Job
//DCHECK_EQ(origin_loop_, MessageLoop::current());
DCHECK(error_ || results_.head());
+ if (requests_trace_)
+ requests_trace_->Add(StringPrintf("Completing job j%d", id_));
+
if (was_cancelled())
return;
@@ -281,6 +342,9 @@ class HostResolverImpl::Job
resolver_->OnJobComplete(this, error_, results_);
}
+ // Immutable. Can be read from either thread,
+ const int id_;
+
// Set on the origin thread, read on the worker thread.
Key key_;
@@ -298,6 +362,9 @@ class HostResolverImpl::Job
// reference ensures that it remains valid until we are done.
scoped_refptr<HostResolverProc> resolver_proc_;
+ // Thread safe log to write details into, or NULL.
+ scoped_refptr<RequestsTrace> requests_trace_;
+
// Assigned on the worker thread, read on the origin thread.
int error_;
AddressList results_;
@@ -463,6 +530,7 @@ HostResolverImpl::HostResolverImpl(
: cache_(cache),
max_jobs_(max_jobs),
next_request_id_(0),
+ next_job_id_(0),
resolver_proc_(resolver_proc),
default_address_family_(ADDRESS_FAMILY_UNSPECIFIED),
shutdown_(false),
@@ -629,10 +697,6 @@ void HostResolverImpl::RemoveObserver(HostResolver::Observer* observer) {
observers_.erase(it);
}
-HostCache* HostResolverImpl::GetHostCache() {
- return cache_.get();
-}
-
void HostResolverImpl::Shutdown() {
shutdown_ = true;
@@ -642,6 +706,42 @@ void HostResolverImpl::Shutdown() {
jobs_.clear();
}
+void HostResolverImpl::ClearRequestsTrace() {
+ if (requests_trace_)
+ requests_trace_->Clear();
+}
+
+void HostResolverImpl::EnableRequestsTracing(bool enable) {
+ requests_trace_ = enable ? new RequestsTrace : NULL;
+ if (enable) {
+ // Print the state of the world when logging was started.
+ requests_trace_->Add("Enabled tracing");
+ requests_trace_->Add(StringPrintf(
+ "Current num outstanding jobs: %d",
+ static_cast<int>(jobs_.size())));
+
+ size_t total = 0u;
+ for (size_t i = 0; i < arraysize(job_pools_); ++i)
+ total += job_pools_[i]->GetNumPendingRequests();
+
+ requests_trace_->Add(StringPrintf(
+ "Number of queued requests: %d", static_cast<int>(total)));
+ }
+}
+
+bool HostResolverImpl::IsRequestsTracingEnabled() const {
+ return !!requests_trace_; // Cast to bool.
+}
+
+scoped_refptr<LoadLog> HostResolverImpl::GetRequestsTrace() {
+ if (!requests_trace_)
+ return NULL;
+
+ scoped_refptr<LoadLog> copy_of_log = new LoadLog(LoadLog::kUnbounded);
+ requests_trace_->Get(copy_of_log);
+ return copy_of_log;
+}
+
void HostResolverImpl::SetPoolConstraints(JobPoolIndex pool_index,
size_t max_outstanding_jobs,
size_t max_pending_requests) {
@@ -722,6 +822,20 @@ void HostResolverImpl::OnStartRequest(LoadLog* load_log,
const RequestInfo& info) {
LoadLog::BeginEvent(load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL);
+ if (requests_trace_) {
+ requests_trace_->Add(StringPrintf(
+ "Received request r%d for {hostname='%s', port=%d, priority=%d, "
+ "speculative=%d, address_family=%d, allow_cached=%d, referrer='%s'}",
+ request_id,
+ info.hostname().c_str(),
+ info.port(),
+ static_cast<int>(info.priority()),
+ static_cast<int>(info.is_speculative()),
+ static_cast<int>(info.address_family()),
+ static_cast<int>(info.allow_cached_response()),
+ info.referrer().spec().c_str()));
+ }
+
// Notify the observers of the start.
if (!observers_.empty()) {
LoadLog::BeginEvent(
@@ -741,6 +855,11 @@ void HostResolverImpl::OnFinishRequest(LoadLog* load_log,
int request_id,
const RequestInfo& info,
int error) {
+ if (requests_trace_) {
+ requests_trace_->Add(StringPrintf(
+ "Finished request r%d with error=%d", request_id, error));
+ }
+
// Notify the observers of the completion.
if (!observers_.empty()) {
LoadLog::BeginEvent(
@@ -764,6 +883,9 @@ void HostResolverImpl::OnCancelRequest(LoadLog* load_log,
const RequestInfo& info) {
LoadLog::AddEvent(load_log, LoadLog::TYPE_CANCELLED);
+ if (requests_trace_)
+ requests_trace_->Add(StringPrintf("Cancelled request r%d", request_id));
+
// Notify the observers of the cancellation.
if (!observers_.empty()) {
LoadLog::BeginEvent(
@@ -829,7 +951,7 @@ void HostResolverImpl::ProcessQueuedRequests() {
HostResolverImpl::Job* HostResolverImpl::CreateAndStartJob(Request* req) {
DCHECK(CanCreateJobForPool(*GetPoolForRequest(req)));
Key key(req->info().hostname(), req->info().address_family());
- scoped_refptr<Job> job = new Job(this, key);
+ scoped_refptr<Job> job = new Job(next_job_id_++, this, key, requests_trace_);
job->AddRequest(req);
AddOutstandingJob(job);
job->Start();
@@ -837,6 +959,9 @@ HostResolverImpl::Job* HostResolverImpl::CreateAndStartJob(Request* req) {
}
int HostResolverImpl::EnqueueRequest(JobPool* pool, Request* req) {
+ if (requests_trace_)
+ requests_trace_->Add(StringPrintf("Queued request r%d", req->id()));
+
scoped_ptr<Request> req_evicted_from_queue(
pool->InsertPendingRequest(req));
@@ -845,6 +970,9 @@ int HostResolverImpl::EnqueueRequest(JobPool* pool, Request* req) {
Request* r = req_evicted_from_queue.get();
int error = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE;
+ if (requests_trace_)
+ requests_trace_->Add(StringPrintf("Evicted request r%d", r->id()));
+
OnFinishRequest(r->load_log(), r->id(), r->info(), error);
if (r == req)
diff --git a/net/base/host_resolver_impl.h b/net/base/host_resolver_impl.h
index 77f9020..f3684b8 100644
--- a/net/base/host_resolver_impl.h
+++ b/net/base/host_resolver_impl.h
@@ -86,7 +86,6 @@ class HostResolverImpl : public HostResolver,
virtual void CancelRequest(RequestHandle req);
virtual void AddObserver(HostResolver::Observer* observer);
virtual void RemoveObserver(HostResolver::Observer* observer);
- virtual HostCache* GetHostCache();
// TODO(eroman): temp hack for http://crbug.com/15513
virtual void Shutdown();
@@ -95,6 +94,22 @@ class HostResolverImpl : public HostResolver,
default_address_family_ = address_family;
}
+ virtual bool IsHostResolverImpl() { return true; }
+
+ // Returns the cache this resolver uses, or NULL if caching is disabled.
+ HostCache* cache() { return cache_.get(); }
+
+ // Clears the request trace log.
+ void ClearRequestsTrace();
+
+ // Starts/ends capturing requests to a trace log.
+ void EnableRequestsTracing(bool enable);
+
+ bool IsRequestsTracingEnabled() const;
+
+ // Returns a copy of the requests trace log, or NULL if there is none.
+ scoped_refptr<LoadLog> GetRequestsTrace();
+
// Applies a set of constraints for requests that belong to the specified
// pool. NOTE: Don't call this after requests have been already been started.
//
@@ -114,6 +129,7 @@ class HostResolverImpl : public HostResolver,
class Job;
class JobPool;
class Request;
+ class RequestsTrace;
typedef std::vector<Request*> RequestsList;
typedef HostCache::Key Key;
typedef std::map<Key, scoped_refptr<Job> > JobMap;
@@ -206,6 +222,10 @@ class HostResolverImpl : public HostResolver,
// Observers are the only consumers of this ID number.
int next_request_id_;
+ // Monotonically increasing ID number to assign to the next job.
+ // The only consumer of this ID is the requests tracing code.
+ int next_job_id_;
+
// The procedure to use for resolving host names. This will be NULL, except
// in the case of unit-tests which inject custom host resolving behaviors.
scoped_refptr<HostResolverProc> resolver_proc_;
@@ -218,6 +238,8 @@ class HostResolverImpl : public HostResolver,
const scoped_refptr<NetworkChangeNotifier> network_change_notifier_;
+ scoped_refptr<RequestsTrace> requests_trace_;
+
DISALLOW_COPY_AND_ASSIGN(HostResolverImpl);
};
diff --git a/net/base/mock_host_resolver.cc b/net/base/mock_host_resolver.cc
index 6f555d3..2185182 100644
--- a/net/base/mock_host_resolver.cc
+++ b/net/base/mock_host_resolver.cc
@@ -66,10 +66,6 @@ void MockHostResolverBase::RemoveObserver(Observer* observer) {
impl_->RemoveObserver(observer);
}
-HostCache* MockHostResolverBase::GetHostCache() {
- return impl_->GetHostCache();
-}
-
void MockHostResolverBase::Shutdown() {
impl_->Shutdown();
}
diff --git a/net/base/mock_host_resolver.h b/net/base/mock_host_resolver.h
index 523935a..8c843b60 100644
--- a/net/base/mock_host_resolver.h
+++ b/net/base/mock_host_resolver.h
@@ -47,7 +47,6 @@ class MockHostResolverBase : public HostResolver {
virtual void CancelRequest(RequestHandle req);
virtual void AddObserver(Observer* observer);
virtual void RemoveObserver(Observer* observer);
- virtual HostCache* GetHostCache();
// TODO(eroman): temp hack for http://crbug.com/18373
virtual void Shutdown();