Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/host_resolver_impl.h" | 5 #include "net/base/host_resolver_impl.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <deque> | 8 #include <deque> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| 11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
| 12 #include "base/debug_util.h" | 12 #include "base/debug_util.h" |
| 13 #include "base/lock.h" | |
| 13 #include "base/message_loop.h" | 14 #include "base/message_loop.h" |
| 14 #include "base/stl_util-inl.h" | 15 #include "base/stl_util-inl.h" |
| 15 #include "base/string_util.h" | 16 #include "base/string_util.h" |
| 16 #include "base/time.h" | 17 #include "base/time.h" |
| 17 #include "base/worker_pool.h" | 18 #include "base/worker_pool.h" |
| 18 #include "net/base/address_list.h" | 19 #include "net/base/address_list.h" |
| 19 #include "net/base/host_resolver_proc.h" | 20 #include "net/base/host_resolver_proc.h" |
| 20 #include "net/base/load_log.h" | 21 #include "net/base/load_log.h" |
| 21 #include "net/base/net_errors.h" | 22 #include "net/base/net_errors.h" |
| 22 #include "net/base/network_change_notifier.h" | 23 #include "net/base/network_change_notifier.h" |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 143 CompletionCallback* callback_; | 144 CompletionCallback* callback_; |
| 144 | 145 |
| 145 // The address list to save result into. | 146 // The address list to save result into. |
| 146 AddressList* addresses_; | 147 AddressList* addresses_; |
| 147 | 148 |
| 148 DISALLOW_COPY_AND_ASSIGN(Request); | 149 DISALLOW_COPY_AND_ASSIGN(Request); |
| 149 }; | 150 }; |
| 150 | 151 |
| 151 //----------------------------------------------------------------------------- | 152 //----------------------------------------------------------------------------- |
| 152 | 153 |
| 154 // Threadsafe log. | |
| 155 class HostResolverImpl::RequestsTrace | |
| 156 : public base::RefCountedThreadSafe<HostResolverImpl::RequestsTrace> { | |
| 157 public: | |
| 158 RequestsTrace() : log_(new LoadLog(LoadLog::kUnbounded)) {} | |
| 159 | |
| 160 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.
| |
| 161 AutoLock l(lock_); | |
| 162 LoadLog::AddString(log_, msg); | |
| 163 } | |
| 164 | |
| 165 void Get(LoadLog* out) { | |
| 166 AutoLock l(lock_); | |
| 167 out->Append(log_); | |
| 168 } | |
| 169 | |
| 170 private: | |
| 171 Lock lock_; | |
| 172 scoped_refptr<LoadLog> log_; | |
| 173 }; | |
| 174 | |
| 175 //----------------------------------------------------------------------------- | |
| 176 | |
| 153 // This class represents a request to the worker pool for a "getaddrinfo()" | 177 // This class represents a request to the worker pool for a "getaddrinfo()" |
| 154 // call. | 178 // call. |
| 155 class HostResolverImpl::Job | 179 class HostResolverImpl::Job |
| 156 : public base::RefCountedThreadSafe<HostResolverImpl::Job> { | 180 : public base::RefCountedThreadSafe<HostResolverImpl::Job> { |
| 157 public: | 181 public: |
| 158 Job(HostResolverImpl* resolver, const Key& key) | 182 Job(int id, HostResolverImpl* resolver, const Key& key, |
| 159 : key_(key), | 183 RequestsTrace* requests_trace) |
| 184 : id_(id), key_(key), | |
| 160 resolver_(resolver), | 185 resolver_(resolver), |
| 161 origin_loop_(MessageLoop::current()), | 186 origin_loop_(MessageLoop::current()), |
| 162 resolver_proc_(resolver->effective_resolver_proc()), | 187 resolver_proc_(resolver->effective_resolver_proc()), |
| 188 requests_trace_(requests_trace), | |
| 163 error_(OK) { | 189 error_(OK) { |
| 190 if (requests_trace_) { | |
| 191 requests_trace_->Add(StringPrintf( | |
| 192 "Created job j%d for {hostname='%s', address_family=%d}", | |
| 193 id_, key.hostname.c_str(), | |
| 194 static_cast<int>(key.address_family))); | |
| 195 } | |
| 164 } | 196 } |
| 165 | 197 |
| 166 // Attaches a request to this job. The job takes ownership of |req| and will | 198 // Attaches a request to this job. The job takes ownership of |req| and will |
| 167 // take care to delete it. | 199 // take care to delete it. |
| 168 void AddRequest(Request* req) { | 200 void AddRequest(Request* req) { |
| 201 if (requests_trace_) { | |
| 202 requests_trace_->Add(StringPrintf( | |
| 203 "Attached request r%d to job j%d", req->id(), id_)); | |
| 204 } | |
| 205 | |
| 169 req->set_job(this); | 206 req->set_job(this); |
| 170 requests_.push_back(req); | 207 requests_.push_back(req); |
| 171 } | 208 } |
| 172 | 209 |
| 173 // Called from origin loop. | 210 // Called from origin loop. |
| 174 void Start() { | 211 void Start() { |
| 212 if (requests_trace_) { | |
|
willchan no longer on Chromium
2010/02/01 19:31:01
No need for the braces
| |
| 213 requests_trace_->Add(StringPrintf("Starting job j%d", id_)); | |
| 214 } | |
| 215 | |
| 175 // Dispatch the job to a worker thread. | 216 // Dispatch the job to a worker thread. |
| 176 if (!WorkerPool::PostTask(FROM_HERE, | 217 if (!WorkerPool::PostTask(FROM_HERE, |
| 177 NewRunnableMethod(this, &Job::DoLookup), true)) { | 218 NewRunnableMethod(this, &Job::DoLookup), true)) { |
| 178 NOTREACHED(); | 219 NOTREACHED(); |
| 179 | 220 |
| 180 // Since we could be running within Resolve() right now, we can't just | 221 // Since we could be running within Resolve() right now, we can't just |
| 181 // call OnLookupComplete(). Instead we must wait until Resolve() has | 222 // call OnLookupComplete(). Instead we must wait until Resolve() has |
| 182 // returned (IO_PENDING). | 223 // returned (IO_PENDING). |
| 183 error_ = ERR_UNEXPECTED; | 224 error_ = ERR_UNEXPECTED; |
| 184 MessageLoop::current()->PostTask( | 225 MessageLoop::current()->PostTask( |
| 185 FROM_HERE, NewRunnableMethod(this, &Job::OnLookupComplete)); | 226 FROM_HERE, NewRunnableMethod(this, &Job::OnLookupComplete)); |
| 186 } | 227 } |
| 187 } | 228 } |
| 188 | 229 |
| 189 // Cancels the current job. Callable from origin thread. | 230 // Cancels the current job. Callable from origin thread. |
| 190 void Cancel() { | 231 void Cancel() { |
| 191 HostResolver* resolver = resolver_; | 232 HostResolver* resolver = resolver_; |
| 192 resolver_ = NULL; | 233 resolver_ = NULL; |
| 193 | 234 |
| 235 if (requests_trace_) | |
| 236 requests_trace_->Add(StringPrintf("Cancelled job j%d", id_)); | |
| 237 | |
| 194 // Mark the job as cancelled, so when worker thread completes it will | 238 // Mark the job as cancelled, so when worker thread completes it will |
| 195 // not try to post completion to origin loop. | 239 // not try to post completion to origin loop. |
| 196 { | 240 { |
| 197 AutoLock locked(origin_loop_lock_); | 241 AutoLock locked(origin_loop_lock_); |
| 198 origin_loop_ = NULL; | 242 origin_loop_ = NULL; |
| 199 } | 243 } |
| 200 | 244 |
| 201 // We will call HostResolverImpl::CancelRequest(Request*) on each one | 245 // We will call HostResolverImpl::CancelRequest(Request*) on each one |
| 202 // in order to notify any observers. | 246 // in order to notify any observers. |
| 203 for (RequestsList::const_iterator it = requests_.begin(); | 247 for (RequestsList::const_iterator it = requests_.begin(); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 232 | 276 |
| 233 private: | 277 private: |
| 234 friend class base::RefCountedThreadSafe<HostResolverImpl::Job>; | 278 friend class base::RefCountedThreadSafe<HostResolverImpl::Job>; |
| 235 | 279 |
| 236 ~Job() { | 280 ~Job() { |
| 237 // Free the requests attached to this job. | 281 // Free the requests attached to this job. |
| 238 STLDeleteElements(&requests_); | 282 STLDeleteElements(&requests_); |
| 239 } | 283 } |
| 240 | 284 |
| 241 void DoLookup() { | 285 void DoLookup() { |
| 286 if (requests_trace_) { | |
| 287 requests_trace_->Add(StringPrintf( | |
| 288 "[resolver thread] Running job j%d", id_)); | |
| 289 } | |
| 290 | |
| 242 // Running on the worker thread | 291 // Running on the worker thread |
| 243 error_ = ResolveAddrInfo(resolver_proc_, | 292 error_ = ResolveAddrInfo(resolver_proc_, |
| 244 key_.hostname, | 293 key_.hostname, |
| 245 key_.address_family, | 294 key_.address_family, |
| 246 &results_); | 295 &results_); |
| 247 | 296 |
| 297 if (requests_trace_) { | |
| 298 requests_trace_->Add(StringPrintf( | |
| 299 "[resolver thread] Completed job j%d", id_)); | |
| 300 } | |
| 301 | |
| 248 Task* reply = NewRunnableMethod(this, &Job::OnLookupComplete); | 302 Task* reply = NewRunnableMethod(this, &Job::OnLookupComplete); |
| 249 | 303 |
| 250 // The origin loop could go away while we are trying to post to it, so we | 304 // The origin loop could go away while we are trying to post to it, so we |
| 251 // need to call its PostTask method inside a lock. See ~HostResolver. | 305 // need to call its PostTask method inside a lock. See ~HostResolver. |
| 252 { | 306 { |
| 253 AutoLock locked(origin_loop_lock_); | 307 AutoLock locked(origin_loop_lock_); |
| 254 if (origin_loop_) { | 308 if (origin_loop_) { |
| 255 origin_loop_->PostTask(FROM_HERE, reply); | 309 origin_loop_->PostTask(FROM_HERE, reply); |
| 256 reply = NULL; | 310 reply = NULL; |
| 257 } | 311 } |
| 258 } | 312 } |
| 259 | 313 |
| 260 // Does nothing if it got posted. | 314 // Does nothing if it got posted. |
| 261 delete reply; | 315 delete reply; |
| 262 } | 316 } |
| 263 | 317 |
| 264 // Callback for when DoLookup() completes (runs on origin thread). | 318 // Callback for when DoLookup() completes (runs on origin thread). |
| 265 void OnLookupComplete() { | 319 void OnLookupComplete() { |
| 266 // Should be running on origin loop. | 320 // Should be running on origin loop. |
| 267 // TODO(eroman): this is being hit by URLRequestTest.CancelTest*, | 321 // TODO(eroman): this is being hit by URLRequestTest.CancelTest*, |
| 268 // because MessageLoop::current() == NULL. | 322 // because MessageLoop::current() == NULL. |
| 269 //DCHECK_EQ(origin_loop_, MessageLoop::current()); | 323 //DCHECK_EQ(origin_loop_, MessageLoop::current()); |
| 270 DCHECK(error_ || results_.head()); | 324 DCHECK(error_ || results_.head()); |
| 271 | 325 |
| 326 if (requests_trace_) | |
| 327 requests_trace_->Add(StringPrintf("Completing job j%d", id_)); | |
| 328 | |
| 272 if (was_cancelled()) | 329 if (was_cancelled()) |
| 273 return; | 330 return; |
| 274 | 331 |
| 275 DCHECK(!requests_.empty()); | 332 DCHECK(!requests_.empty()); |
| 276 | 333 |
| 277 // Use the port number of the first request. | 334 // Use the port number of the first request. |
| 278 if (error_ == OK) | 335 if (error_ == OK) |
| 279 results_.SetPort(requests_[0]->port()); | 336 results_.SetPort(requests_[0]->port()); |
| 280 | 337 |
| 281 resolver_->OnJobComplete(this, error_, results_); | 338 resolver_->OnJobComplete(this, error_, results_); |
| 282 } | 339 } |
| 283 | 340 |
| 341 // Immutable. Can be read from either thread, | |
| 342 const int id_; | |
| 343 | |
| 284 // Set on the origin thread, read on the worker thread. | 344 // Set on the origin thread, read on the worker thread. |
| 285 Key key_; | 345 Key key_; |
| 286 | 346 |
| 287 // Only used on the origin thread (where Resolve was called). | 347 // Only used on the origin thread (where Resolve was called). |
| 288 HostResolverImpl* resolver_; | 348 HostResolverImpl* resolver_; |
| 289 RequestsList requests_; // The requests waiting on this job. | 349 RequestsList requests_; // The requests waiting on this job. |
| 290 | 350 |
| 291 // Used to post ourselves onto the origin thread. | 351 // Used to post ourselves onto the origin thread. |
| 292 Lock origin_loop_lock_; | 352 Lock origin_loop_lock_; |
| 293 MessageLoop* origin_loop_; | 353 MessageLoop* origin_loop_; |
| 294 | 354 |
| 295 // Hold an owning reference to the HostResolverProc that we are going to use. | 355 // Hold an owning reference to the HostResolverProc that we are going to use. |
| 296 // This may not be the current resolver procedure by the time we call | 356 // This may not be the current resolver procedure by the time we call |
| 297 // ResolveAddrInfo, but that's OK... we'll use it anyways, and the owning | 357 // ResolveAddrInfo, but that's OK... we'll use it anyways, and the owning |
| 298 // reference ensures that it remains valid until we are done. | 358 // reference ensures that it remains valid until we are done. |
| 299 scoped_refptr<HostResolverProc> resolver_proc_; | 359 scoped_refptr<HostResolverProc> resolver_proc_; |
| 300 | 360 |
| 361 // Thread safe log to write details into, or NULL. | |
| 362 scoped_refptr<RequestsTrace> requests_trace_; | |
| 363 | |
| 301 // Assigned on the worker thread, read on the origin thread. | 364 // Assigned on the worker thread, read on the origin thread. |
| 302 int error_; | 365 int error_; |
| 303 AddressList results_; | 366 AddressList results_; |
| 304 | 367 |
| 305 DISALLOW_COPY_AND_ASSIGN(Job); | 368 DISALLOW_COPY_AND_ASSIGN(Job); |
| 306 }; | 369 }; |
| 307 | 370 |
| 308 //----------------------------------------------------------------------------- | 371 //----------------------------------------------------------------------------- |
| 309 | 372 |
| 310 // We rely on the priority enum values being sequential having starting at 0, | 373 // We rely on the priority enum values being sequential having starting at 0, |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 456 //----------------------------------------------------------------------------- | 519 //----------------------------------------------------------------------------- |
| 457 | 520 |
| 458 HostResolverImpl::HostResolverImpl( | 521 HostResolverImpl::HostResolverImpl( |
| 459 HostResolverProc* resolver_proc, | 522 HostResolverProc* resolver_proc, |
| 460 HostCache* cache, | 523 HostCache* cache, |
| 461 const scoped_refptr<NetworkChangeNotifier>& network_change_notifier, | 524 const scoped_refptr<NetworkChangeNotifier>& network_change_notifier, |
| 462 size_t max_jobs) | 525 size_t max_jobs) |
| 463 : cache_(cache), | 526 : cache_(cache), |
| 464 max_jobs_(max_jobs), | 527 max_jobs_(max_jobs), |
| 465 next_request_id_(0), | 528 next_request_id_(0), |
| 529 next_job_id_(0), | |
| 466 resolver_proc_(resolver_proc), | 530 resolver_proc_(resolver_proc), |
| 467 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), | 531 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), |
| 468 shutdown_(false), | 532 shutdown_(false), |
| 469 network_change_notifier_(network_change_notifier) { | 533 network_change_notifier_(network_change_notifier) { |
| 470 DCHECK_GT(max_jobs, 0u); | 534 DCHECK_GT(max_jobs, 0u); |
| 471 | 535 |
| 472 // It is cumbersome to expose all of the constraints in the constructor, | 536 // It is cumbersome to expose all of the constraints in the constructor, |
| 473 // so we choose some defaults, which users can override later. | 537 // so we choose some defaults, which users can override later. |
| 474 job_pools_[POOL_NORMAL] = new JobPool(max_jobs, 100u * max_jobs); | 538 job_pools_[POOL_NORMAL] = new JobPool(max_jobs, 100u * max_jobs); |
| 475 | 539 |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 622 void HostResolverImpl::RemoveObserver(HostResolver::Observer* observer) { | 686 void HostResolverImpl::RemoveObserver(HostResolver::Observer* observer) { |
| 623 ObserversList::iterator it = | 687 ObserversList::iterator it = |
| 624 std::find(observers_.begin(), observers_.end(), observer); | 688 std::find(observers_.begin(), observers_.end(), observer); |
| 625 | 689 |
| 626 // Observer must exist. | 690 // Observer must exist. |
| 627 DCHECK(it != observers_.end()); | 691 DCHECK(it != observers_.end()); |
| 628 | 692 |
| 629 observers_.erase(it); | 693 observers_.erase(it); |
| 630 } | 694 } |
| 631 | 695 |
| 632 HostCache* HostResolverImpl::GetHostCache() { | |
| 633 return cache_.get(); | |
| 634 } | |
| 635 | |
| 636 void HostResolverImpl::Shutdown() { | 696 void HostResolverImpl::Shutdown() { |
| 637 shutdown_ = true; | 697 shutdown_ = true; |
| 638 | 698 |
| 639 // Cancel the outstanding jobs. | 699 // Cancel the outstanding jobs. |
| 640 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ++it) | 700 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ++it) |
| 641 it->second->Cancel(); | 701 it->second->Cancel(); |
| 642 jobs_.clear(); | 702 jobs_.clear(); |
| 643 } | 703 } |
| 644 | 704 |
| 705 void HostResolverImpl::ClearRequestsTrace() { | |
| 706 requests_trace_ = NULL; | |
| 707 } | |
| 708 | |
| 709 void HostResolverImpl::EnableRequestsTracing(bool enable) { | |
| 710 requests_trace_ = enable ? new RequestsTrace : NULL; | |
| 711 if (enable) { | |
| 712 // Print the state of the world when logging was started. | |
| 713 requests_trace_->Add("Enabled tracing"); | |
| 714 requests_trace_->Add(StringPrintf( | |
| 715 "Current num outstanding jobs: %d", | |
| 716 static_cast<int>(jobs_.size()))); | |
| 717 | |
| 718 size_t total = 0u; | |
| 719 for (size_t i = 0; i < arraysize(job_pools_); ++i) | |
| 720 total += job_pools_[i]->GetNumPendingRequests(); | |
| 721 | |
| 722 requests_trace_->Add(StringPrintf( | |
| 723 "Number of queued requests: %d", static_cast<int>(total))); | |
| 724 } | |
| 725 } | |
| 726 | |
| 727 bool HostResolverImpl::IsRequestsTracingEnabled() const { | |
| 728 return !!requests_trace_; // Cast to bool. | |
| 729 } | |
| 730 | |
| 731 scoped_refptr<LoadLog> HostResolverImpl::GetRequestsTrace() { | |
| 732 if (!requests_trace_) | |
| 733 return NULL; | |
| 734 | |
| 735 scoped_refptr<LoadLog> copy_of_log = new LoadLog(LoadLog::kUnbounded); | |
| 736 requests_trace_->Get(copy_of_log); | |
| 737 return copy_of_log; | |
| 738 } | |
| 739 | |
| 645 void HostResolverImpl::SetPoolConstraints(JobPoolIndex pool_index, | 740 void HostResolverImpl::SetPoolConstraints(JobPoolIndex pool_index, |
| 646 size_t max_outstanding_jobs, | 741 size_t max_outstanding_jobs, |
| 647 size_t max_pending_requests) { | 742 size_t max_pending_requests) { |
| 648 CHECK(pool_index >= 0); | 743 CHECK(pool_index >= 0); |
| 649 CHECK(pool_index < POOL_COUNT); | 744 CHECK(pool_index < POOL_COUNT); |
| 650 CHECK(jobs_.empty()) << "Can only set constraints during setup"; | 745 CHECK(jobs_.empty()) << "Can only set constraints during setup"; |
| 651 JobPool* pool = job_pools_[pool_index]; | 746 JobPool* pool = job_pools_[pool_index]; |
| 652 pool->SetConstraints(max_outstanding_jobs, max_pending_requests); | 747 pool->SetConstraints(max_outstanding_jobs, max_pending_requests); |
| 653 } | 748 } |
| 654 | 749 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 715 } | 810 } |
| 716 | 811 |
| 717 cur_completing_job_ = NULL; | 812 cur_completing_job_ = NULL; |
| 718 } | 813 } |
| 719 | 814 |
| 720 void HostResolverImpl::OnStartRequest(LoadLog* load_log, | 815 void HostResolverImpl::OnStartRequest(LoadLog* load_log, |
| 721 int request_id, | 816 int request_id, |
| 722 const RequestInfo& info) { | 817 const RequestInfo& info) { |
| 723 LoadLog::BeginEvent(load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL); | 818 LoadLog::BeginEvent(load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL); |
| 724 | 819 |
| 820 if (requests_trace_) { | |
| 821 requests_trace_->Add(StringPrintf( | |
| 822 "Received request r%d for {hostname='%s', port=%d, priority=%d, " | |
| 823 "speculative=%d, address_family=%d, allow_cached=%d, referrer=%s}", | |
| 824 request_id, | |
| 825 info.hostname().c_str(), | |
| 826 info.port(), | |
| 827 static_cast<int>(info.priority()), | |
| 828 static_cast<int>(info.is_speculative()), | |
| 829 static_cast<int>(info.address_family()), | |
| 830 static_cast<int>(info.allow_cached_response()), | |
| 831 info.referrer().spec().c_str())); | |
| 832 } | |
| 833 | |
| 725 // Notify the observers of the start. | 834 // Notify the observers of the start. |
| 726 if (!observers_.empty()) { | 835 if (!observers_.empty()) { |
| 727 LoadLog::BeginEvent( | 836 LoadLog::BeginEvent( |
| 728 load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART); | 837 load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART); |
| 729 | 838 |
| 730 for (ObserversList::iterator it = observers_.begin(); | 839 for (ObserversList::iterator it = observers_.begin(); |
| 731 it != observers_.end(); ++it) { | 840 it != observers_.end(); ++it) { |
| 732 (*it)->OnStartResolution(request_id, info); | 841 (*it)->OnStartResolution(request_id, info); |
| 733 } | 842 } |
| 734 | 843 |
| 735 LoadLog::EndEvent( | 844 LoadLog::EndEvent( |
| 736 load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART); | 845 load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART); |
| 737 } | 846 } |
| 738 } | 847 } |
| 739 | 848 |
| 740 void HostResolverImpl::OnFinishRequest(LoadLog* load_log, | 849 void HostResolverImpl::OnFinishRequest(LoadLog* load_log, |
| 741 int request_id, | 850 int request_id, |
| 742 const RequestInfo& info, | 851 const RequestInfo& info, |
| 743 int error) { | 852 int error) { |
| 853 if (requests_trace_) { | |
| 854 requests_trace_->Add(StringPrintf( | |
| 855 "Finished request r%d with error=%d", request_id, error)); | |
| 856 } | |
| 857 | |
| 744 // Notify the observers of the completion. | 858 // Notify the observers of the completion. |
| 745 if (!observers_.empty()) { | 859 if (!observers_.empty()) { |
| 746 LoadLog::BeginEvent( | 860 LoadLog::BeginEvent( |
| 747 load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONFINISH); | 861 load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONFINISH); |
| 748 | 862 |
| 749 bool was_resolved = error == OK; | 863 bool was_resolved = error == OK; |
| 750 for (ObserversList::iterator it = observers_.begin(); | 864 for (ObserversList::iterator it = observers_.begin(); |
| 751 it != observers_.end(); ++it) { | 865 it != observers_.end(); ++it) { |
| 752 (*it)->OnFinishResolutionWithStatus(request_id, was_resolved, info); | 866 (*it)->OnFinishResolutionWithStatus(request_id, was_resolved, info); |
| 753 } | 867 } |
| 754 | 868 |
| 755 LoadLog::EndEvent( | 869 LoadLog::EndEvent( |
| 756 load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONFINISH); | 870 load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONFINISH); |
| 757 } | 871 } |
| 758 | 872 |
| 759 LoadLog::EndEvent(load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL); | 873 LoadLog::EndEvent(load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL); |
| 760 } | 874 } |
| 761 | 875 |
| 762 void HostResolverImpl::OnCancelRequest(LoadLog* load_log, | 876 void HostResolverImpl::OnCancelRequest(LoadLog* load_log, |
| 763 int request_id, | 877 int request_id, |
| 764 const RequestInfo& info) { | 878 const RequestInfo& info) { |
| 765 LoadLog::AddEvent(load_log, LoadLog::TYPE_CANCELLED); | 879 LoadLog::AddEvent(load_log, LoadLog::TYPE_CANCELLED); |
| 766 | 880 |
| 881 if (requests_trace_) | |
| 882 requests_trace_->Add(StringPrintf("Cancelled request r%d", request_id)); | |
| 883 | |
| 767 // Notify the observers of the cancellation. | 884 // Notify the observers of the cancellation. |
| 768 if (!observers_.empty()) { | 885 if (!observers_.empty()) { |
| 769 LoadLog::BeginEvent( | 886 LoadLog::BeginEvent( |
| 770 load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONCANCEL); | 887 load_log, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONCANCEL); |
| 771 | 888 |
| 772 for (ObserversList::iterator it = observers_.begin(); | 889 for (ObserversList::iterator it = observers_.begin(); |
| 773 it != observers_.end(); ++it) { | 890 it != observers_.end(); ++it) { |
| 774 (*it)->OnCancelResolution(request_id, info); | 891 (*it)->OnCancelResolution(request_id, info); |
| 775 } | 892 } |
| 776 | 893 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 822 // Search for any other pending request which can piggy-back off this job. | 939 // Search for any other pending request which can piggy-back off this job. |
| 823 for (size_t pool_i = 0; pool_i < POOL_COUNT; ++pool_i) { | 940 for (size_t pool_i = 0; pool_i < POOL_COUNT; ++pool_i) { |
| 824 JobPool* pool = job_pools_[pool_i]; | 941 JobPool* pool = job_pools_[pool_i]; |
| 825 pool->MoveRequestsToJob(job); | 942 pool->MoveRequestsToJob(job); |
| 826 } | 943 } |
| 827 } | 944 } |
| 828 | 945 |
| 829 HostResolverImpl::Job* HostResolverImpl::CreateAndStartJob(Request* req) { | 946 HostResolverImpl::Job* HostResolverImpl::CreateAndStartJob(Request* req) { |
| 830 DCHECK(CanCreateJobForPool(*GetPoolForRequest(req))); | 947 DCHECK(CanCreateJobForPool(*GetPoolForRequest(req))); |
| 831 Key key(req->info().hostname(), req->info().address_family()); | 948 Key key(req->info().hostname(), req->info().address_family()); |
| 832 scoped_refptr<Job> job = new Job(this, key); | 949 scoped_refptr<Job> job = new Job(next_job_id_++, this, key, requests_trace_); |
| 833 job->AddRequest(req); | 950 job->AddRequest(req); |
| 834 AddOutstandingJob(job); | 951 AddOutstandingJob(job); |
| 835 job->Start(); | 952 job->Start(); |
| 836 return job.get(); | 953 return job.get(); |
| 837 } | 954 } |
| 838 | 955 |
| 839 int HostResolverImpl::EnqueueRequest(JobPool* pool, Request* req) { | 956 int HostResolverImpl::EnqueueRequest(JobPool* pool, Request* req) { |
| 957 if (requests_trace_) | |
| 958 requests_trace_->Add(StringPrintf("Queued request r%d", req->id())); | |
| 959 | |
| 840 scoped_ptr<Request> req_evicted_from_queue( | 960 scoped_ptr<Request> req_evicted_from_queue( |
| 841 pool->InsertPendingRequest(req)); | 961 pool->InsertPendingRequest(req)); |
| 842 | 962 |
| 843 // If the queue has become too large, we need to kick something out. | 963 // If the queue has become too large, we need to kick something out. |
| 844 if (req_evicted_from_queue.get()) { | 964 if (req_evicted_from_queue.get()) { |
| 845 Request* r = req_evicted_from_queue.get(); | 965 Request* r = req_evicted_from_queue.get(); |
| 846 int error = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE; | 966 int error = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE; |
| 847 | 967 |
| 968 if (requests_trace_) | |
| 969 requests_trace_->Add(StringPrintf("Evicted request r%d", r->id())); | |
| 970 | |
| 848 OnFinishRequest(r->load_log(), r->id(), r->info(), error); | 971 OnFinishRequest(r->load_log(), r->id(), r->info(), error); |
| 849 | 972 |
| 850 if (r == req) | 973 if (r == req) |
| 851 return error; | 974 return error; |
| 852 | 975 |
| 853 r->OnComplete(error, AddressList()); | 976 r->OnComplete(error, AddressList()); |
| 854 } | 977 } |
| 855 | 978 |
| 856 return ERR_IO_PENDING; | 979 return ERR_IO_PENDING; |
| 857 } | 980 } |
| 858 | 981 |
| 859 } // namespace net | 982 } // namespace net |
| OLD | NEW |