Index: net/base/host_resolver_impl.cc |
=================================================================== |
--- net/base/host_resolver_impl.cc (revision 37608) |
+++ net/base/host_resolver_impl.cc (working copy) |
@@ -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,68 @@ |
//----------------------------------------------------------------------------- |
+// Threadsafe log. |
+class HostResolverImpl::RequestsTrace |
+ : public base::RefCountedThreadSafe<HostResolverImpl::RequestsTrace> { |
+ public: |
+ RequestsTrace() : log_(new LoadLog(LoadLog::kUnbounded)) {} |
+ |
+ void Add(const std::string& msg) { |
willchan no longer on Chromium
2010/02/01 19:31:01
I don't care too much, but my impression is that w
eroman
2010/02/01 20:31:25
Since the locking is *only* going to be used in ca
willchan no longer on Chromium
2010/02/01 21:27:33
I agree the performance isn't an issue.
|
+ AutoLock l(lock_); |
+ LoadLog::AddString(log_, msg); |
+ } |
+ |
+ void Get(LoadLog* out) { |
+ AutoLock l(lock_); |
+ out->Append(log_); |
+ } |
+ |
+ 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_) { |
willchan no longer on Chromium
2010/02/01 19:31:01
No need for the braces
|
+ 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 +232,9 @@ |
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 +283,22 @@ |
} |
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 +323,9 @@ |
//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 +338,9 @@ |
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 +358,9 @@ |
// 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 +526,7 @@ |
: 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 +693,6 @@ |
observers_.erase(it); |
} |
-HostCache* HostResolverImpl::GetHostCache() { |
- return cache_.get(); |
-} |
- |
void HostResolverImpl::Shutdown() { |
shutdown_ = true; |
@@ -642,6 +702,41 @@ |
jobs_.clear(); |
} |
+void HostResolverImpl::ClearRequestsTrace() { |
+ requests_trace_ = NULL; |
+} |
+ |
+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 +817,20 @@ |
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 +850,11 @@ |
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 +878,9 @@ |
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 +946,7 @@ |
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 +954,9 @@ |
} |
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 +965,9 @@ |
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) |