| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <Winsock2.h> | 8 #include <Winsock2.h> |
| 9 #elif defined(OS_POSIX) | 9 #elif defined(OS_POSIX) |
| 10 #include <netdb.h> | 10 #include <netdb.h> |
| 11 #endif | 11 #endif |
| 12 | 12 |
| 13 #include <cmath> | 13 #include <cmath> |
| 14 #include <deque> | 14 #include <deque> |
| 15 #include <vector> | 15 #include <vector> |
| 16 | 16 |
| 17 #include "base/basictypes.h" | 17 #include "base/basictypes.h" |
| 18 #include "base/compiler_specific.h" | 18 #include "base/compiler_specific.h" |
| 19 #include "base/debug_util.h" | 19 #include "base/debug_util.h" |
| 20 #include "base/histogram.h" | 20 #include "base/histogram.h" |
| 21 #include "base/lock.h" | 21 #include "base/lock.h" |
| 22 #include "base/message_loop.h" | 22 #include "base/message_loop.h" |
| 23 #include "base/stl_util-inl.h" | 23 #include "base/stl_util-inl.h" |
| 24 #include "base/string_util.h" | 24 #include "base/string_util.h" |
| 25 #include "base/time.h" | 25 #include "base/time.h" |
| 26 #include "base/utf_string_conversions.h" | 26 #include "base/utf_string_conversions.h" |
| 27 #include "base/values.h" | 27 #include "base/values.h" |
| 28 #include "base/worker_pool.h" | 28 #include "base/worker_pool.h" |
| 29 #include "net/base/address_list.h" | 29 #include "net/base/address_list.h" |
| 30 #include "net/base/address_list_net_log_param.h" |
| 31 #include "net/base/host_port_pair.h" |
| 30 #include "net/base/host_resolver_proc.h" | 32 #include "net/base/host_resolver_proc.h" |
| 33 #include "net/base/net_errors.h" |
| 31 #include "net/base/net_log.h" | 34 #include "net/base/net_log.h" |
| 32 #include "net/base/net_errors.h" | |
| 33 #include "net/base/net_util.h" | 35 #include "net/base/net_util.h" |
| 34 | 36 |
| 35 #if defined(OS_WIN) | 37 #if defined(OS_WIN) |
| 36 #include "net/base/winsock_init.h" | 38 #include "net/base/winsock_init.h" |
| 37 #endif | 39 #endif |
| 38 | 40 |
| 39 namespace net { | 41 namespace net { |
| 40 | 42 |
| 41 namespace { | 43 namespace { |
| 42 | 44 |
| 43 HostCache* CreateDefaultCache() { | 45 HostCache* CreateDefaultCache() { |
| 44 static const size_t kMaxHostCacheEntries = 100; | 46 static const size_t kMaxHostCacheEntries = 100; |
| 45 | 47 |
| 46 HostCache* cache = new HostCache( | 48 HostCache* cache = new HostCache( |
| 47 kMaxHostCacheEntries, | 49 kMaxHostCacheEntries, |
| 48 base::TimeDelta::FromMinutes(1), | 50 base::TimeDelta::FromMinutes(1), |
| 49 base::TimeDelta::FromSeconds(0)); // Disable caching of failed DNS. | 51 base::TimeDelta::FromSeconds(0)); // Disable caching of failed DNS. |
| 50 | 52 |
| 51 return cache; | 53 return cache; |
| 52 } | 54 } |
| 53 | 55 |
| 54 } // anonymous namespace | 56 } // anonymous namespace |
| 55 | 57 |
| 56 HostResolver* CreateSystemHostResolver(size_t max_concurrent_resolves) { | 58 HostResolver* CreateSystemHostResolver(size_t max_concurrent_resolves, |
| 59 NetLog* net_log) { |
| 57 // Maximum of 50 concurrent threads. | 60 // Maximum of 50 concurrent threads. |
| 58 // TODO(eroman): Adjust this, do some A/B experiments. | 61 // TODO(eroman): Adjust this, do some A/B experiments. |
| 59 static const size_t kDefaultMaxJobs = 50u; | 62 static const size_t kDefaultMaxJobs = 50u; |
| 60 | 63 |
| 61 if (max_concurrent_resolves == HostResolver::kDefaultParallelism) | 64 if (max_concurrent_resolves == HostResolver::kDefaultParallelism) |
| 62 max_concurrent_resolves = kDefaultMaxJobs; | 65 max_concurrent_resolves = kDefaultMaxJobs; |
| 63 | 66 |
| 64 HostResolverImpl* resolver = | 67 HostResolverImpl* resolver = |
| 65 new HostResolverImpl(NULL, CreateDefaultCache(), | 68 new HostResolverImpl(NULL, CreateDefaultCache(), |
| 66 max_concurrent_resolves); | 69 max_concurrent_resolves, net_log); |
| 67 | 70 |
| 68 return resolver; | 71 return resolver; |
| 69 } | 72 } |
| 70 | 73 |
| 71 static int ResolveAddrInfo(HostResolverProc* resolver_proc, | 74 static int ResolveAddrInfo(HostResolverProc* resolver_proc, |
| 72 const std::string& host, | 75 const std::string& host, |
| 73 AddressFamily address_family, | 76 AddressFamily address_family, |
| 74 HostResolverFlags host_resolver_flags, | 77 HostResolverFlags host_resolver_flags, |
| 75 AddressList* out, | 78 AddressList* out, |
| 76 int* os_error) { | 79 int* os_error) { |
| 77 if (resolver_proc) { | 80 if (resolver_proc) { |
| 78 // Use the custom procedure. | 81 // Use the custom procedure. |
| 79 return resolver_proc->Resolve(host, address_family, | 82 return resolver_proc->Resolve(host, address_family, |
| 80 host_resolver_flags, out, os_error); | 83 host_resolver_flags, out, os_error); |
| 81 } else { | 84 } else { |
| 82 // Use the system procedure (getaddrinfo). | 85 // Use the system procedure (getaddrinfo). |
| 83 return SystemHostResolverProc(host, address_family, | 86 return SystemHostResolverProc(host, address_family, |
| 84 host_resolver_flags, out, os_error); | 87 host_resolver_flags, out, os_error); |
| 85 } | 88 } |
| 86 } | 89 } |
| 87 | 90 |
| 88 // Extra parameters to attach to the NetLog when the resolve failed. | 91 // Extra parameters to attach to the NetLog when the resolve failed. |
| 89 class HostResolveFailedParams : public NetLog::EventParameters { | 92 class HostResolveFailedParams : public NetLog::EventParameters { |
| 90 public: | 93 public: |
| 91 HostResolveFailedParams(int net_error, int os_error, bool was_from_cache) | 94 HostResolveFailedParams(int net_error, int os_error) |
| 92 : net_error_(net_error), | 95 : net_error_(net_error), |
| 93 os_error_(os_error), | 96 os_error_(os_error) { |
| 94 was_from_cache_(was_from_cache) { | |
| 95 } | 97 } |
| 96 | 98 |
| 97 virtual Value* ToValue() const { | 99 virtual Value* ToValue() const { |
| 98 DictionaryValue* dict = new DictionaryValue(); | 100 DictionaryValue* dict = new DictionaryValue(); |
| 99 dict->SetInteger("net_error", net_error_); | 101 dict->SetInteger("net_error", net_error_); |
| 100 dict->SetBoolean("was_from_cache", was_from_cache_); | |
| 101 | 102 |
| 102 if (os_error_) { | 103 if (os_error_) { |
| 103 dict->SetInteger("os_error", os_error_); | 104 dict->SetInteger("os_error", os_error_); |
| 104 #if defined(OS_POSIX) | 105 #if defined(OS_POSIX) |
| 105 dict->SetString("os_error_string", gai_strerror(os_error_)); | 106 dict->SetString("os_error_string", gai_strerror(os_error_)); |
| 106 #elif defined(OS_WIN) | 107 #elif defined(OS_WIN) |
| 107 // Map the error code to a human-readable string. | 108 // Map the error code to a human-readable string. |
| 108 LPWSTR error_string = NULL; | 109 LPWSTR error_string = NULL; |
| 109 int size = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | | 110 int size = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | |
| 110 FORMAT_MESSAGE_FROM_SYSTEM, | 111 FORMAT_MESSAGE_FROM_SYSTEM, |
| 111 0, // Use the internal message table. | 112 0, // Use the internal message table. |
| 112 os_error_, | 113 os_error_, |
| 113 0, // Use default language. | 114 0, // Use default language. |
| 114 (LPWSTR)&error_string, | 115 (LPWSTR)&error_string, |
| 115 0, // Buffer size. | 116 0, // Buffer size. |
| 116 0); // Arguments (unused). | 117 0); // Arguments (unused). |
| 117 dict->SetString("os_error_string", WideToUTF8(error_string)); | 118 dict->SetString("os_error_string", WideToUTF8(error_string)); |
| 118 LocalFree(error_string); | 119 LocalFree(error_string); |
| 119 #endif | 120 #endif |
| 120 } | 121 } |
| 121 | 122 |
| 122 return dict; | 123 return dict; |
| 123 } | 124 } |
| 124 | 125 |
| 125 private: | 126 private: |
| 126 const int net_error_; | 127 const int net_error_; |
| 127 const int os_error_; | 128 const int os_error_; |
| 128 const bool was_from_cache_; | 129 }; |
| 130 |
| 131 // Parameters representing the information in a RequestInfo object, along with |
| 132 // the associated NetLog::Source. |
| 133 class RequestInfoParameters : public NetLog::EventParameters { |
| 134 public: |
| 135 RequestInfoParameters(const HostResolver::RequestInfo& info, |
| 136 const NetLog::Source& source) |
| 137 : info_(info), source_(source) {} |
| 138 |
| 139 virtual Value* ToValue() const { |
| 140 DictionaryValue* dict = new DictionaryValue(); |
| 141 dict->SetString("host", HostPortPair(info_.hostname(), |
| 142 info_.port()).ToString()); |
| 143 dict->SetInteger("address_family", |
| 144 static_cast<int>(info_.address_family())); |
| 145 dict->SetBoolean("allow_cached_response", info_.allow_cached_response()); |
| 146 dict->SetBoolean("is_speculative", info_.is_speculative()); |
| 147 dict->SetInteger("priority", info_.priority()); |
| 148 |
| 149 if (source_.is_valid()) |
| 150 dict->Set("source_dependency", source_.ToValue()); |
| 151 |
| 152 return dict; |
| 153 } |
| 154 |
| 155 private: |
| 156 const HostResolver::RequestInfo info_; |
| 157 const NetLog::Source source_; |
| 158 }; |
| 159 |
| 160 // Parameters associated with the creation of a HostResolveImpl::Job. |
| 161 class JobCreationParameters : public NetLog::EventParameters { |
| 162 public: |
| 163 JobCreationParameters(const std::string& host, const NetLog::Source& source) |
| 164 : host_(host), source_(source) {} |
| 165 |
| 166 virtual Value* ToValue() const { |
| 167 DictionaryValue* dict = new DictionaryValue(); |
| 168 dict->SetString("host", host_); |
| 169 dict->Set("source_dependency", source_.ToValue()); |
| 170 return dict; |
| 171 } |
| 172 |
| 173 private: |
| 174 const std::string host_; |
| 175 const NetLog::Source source_; |
| 129 }; | 176 }; |
| 130 | 177 |
| 131 // Gets a list of the likely error codes that getaddrinfo() can return | 178 // Gets a list of the likely error codes that getaddrinfo() can return |
| 132 // (non-exhaustive). These are the error codes that we will track via | 179 // (non-exhaustive). These are the error codes that we will track via |
| 133 // a histogram. | 180 // a histogram. |
| 134 std::vector<int> GetAllGetAddrinfoOSErrors() { | 181 std::vector<int> GetAllGetAddrinfoOSErrors() { |
| 135 int os_errors[] = { | 182 int os_errors[] = { |
| 136 #if defined(OS_POSIX) | 183 #if defined(OS_POSIX) |
| 137 EAI_ADDRFAMILY, | 184 EAI_ADDRFAMILY, |
| 138 EAI_AGAIN, | 185 EAI_AGAIN, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 169 // won't fall into the same buckets as the expected ones. | 216 // won't fall into the same buckets as the expected ones. |
| 170 errors.push_back(std::abs(os_errors[i]) + 1); | 217 errors.push_back(std::abs(os_errors[i]) + 1); |
| 171 } | 218 } |
| 172 return errors; | 219 return errors; |
| 173 } | 220 } |
| 174 | 221 |
| 175 //----------------------------------------------------------------------------- | 222 //----------------------------------------------------------------------------- |
| 176 | 223 |
| 177 class HostResolverImpl::Request { | 224 class HostResolverImpl::Request { |
| 178 public: | 225 public: |
| 179 Request(const BoundNetLog& net_log, | 226 Request(const BoundNetLog& source_net_log, |
| 227 const BoundNetLog& request_net_log, |
| 180 int id, | 228 int id, |
| 181 const RequestInfo& info, | 229 const RequestInfo& info, |
| 182 CompletionCallback* callback, | 230 CompletionCallback* callback, |
| 183 AddressList* addresses) | 231 AddressList* addresses) |
| 184 : net_log_(net_log), | 232 : source_net_log_(source_net_log), |
| 233 request_net_log_(request_net_log), |
| 185 id_(id), | 234 id_(id), |
| 186 info_(info), | 235 info_(info), |
| 187 job_(NULL), | 236 job_(NULL), |
| 188 callback_(callback), | 237 callback_(callback), |
| 189 addresses_(addresses) { | 238 addresses_(addresses) { |
| 190 } | 239 } |
| 191 | 240 |
| 192 // Mark the request as cancelled. | 241 // Mark the request as cancelled. |
| 193 void MarkAsCancelled() { | 242 void MarkAsCancelled() { |
| 194 job_ = NULL; | 243 job_ = NULL; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 213 } | 262 } |
| 214 | 263 |
| 215 int port() const { | 264 int port() const { |
| 216 return info_.port(); | 265 return info_.port(); |
| 217 } | 266 } |
| 218 | 267 |
| 219 Job* job() const { | 268 Job* job() const { |
| 220 return job_; | 269 return job_; |
| 221 } | 270 } |
| 222 | 271 |
| 223 const BoundNetLog& net_log() { | 272 const BoundNetLog& source_net_log() { |
| 224 return net_log_; | 273 return source_net_log_; |
| 274 } |
| 275 |
| 276 const BoundNetLog& request_net_log() { |
| 277 return request_net_log_; |
| 225 } | 278 } |
| 226 | 279 |
| 227 int id() const { | 280 int id() const { |
| 228 return id_; | 281 return id_; |
| 229 } | 282 } |
| 230 | 283 |
| 231 const RequestInfo& info() const { | 284 const RequestInfo& info() const { |
| 232 return info_; | 285 return info_; |
| 233 } | 286 } |
| 234 | 287 |
| 235 private: | 288 private: |
| 236 BoundNetLog net_log_; | 289 BoundNetLog source_net_log_; |
| 290 BoundNetLog request_net_log_; |
| 237 | 291 |
| 238 // Unique ID for this request. Used by observers to identify requests. | 292 // Unique ID for this request. Used by observers to identify requests. |
| 239 int id_; | 293 int id_; |
| 240 | 294 |
| 241 // The request info that started the request. | 295 // The request info that started the request. |
| 242 RequestInfo info_; | 296 RequestInfo info_; |
| 243 | 297 |
| 244 // The resolve job (running in worker pool) that this request is dependent on. | 298 // The resolve job (running in worker pool) that this request is dependent on. |
| 245 Job* job_; | 299 Job* job_; |
| 246 | 300 |
| 247 // The user's callback to invoke when the request completes. | 301 // The user's callback to invoke when the request completes. |
| 248 CompletionCallback* callback_; | 302 CompletionCallback* callback_; |
| 249 | 303 |
| 250 // The address list to save result into. | 304 // The address list to save result into. |
| 251 AddressList* addresses_; | 305 AddressList* addresses_; |
| 252 | 306 |
| 253 DISALLOW_COPY_AND_ASSIGN(Request); | 307 DISALLOW_COPY_AND_ASSIGN(Request); |
| 254 }; | 308 }; |
| 255 | 309 |
| 256 //----------------------------------------------------------------------------- | 310 //----------------------------------------------------------------------------- |
| 257 | 311 |
| 258 // This class represents a request to the worker pool for a "getaddrinfo()" | 312 // This class represents a request to the worker pool for a "getaddrinfo()" |
| 259 // call. | 313 // call. |
| 260 class HostResolverImpl::Job | 314 class HostResolverImpl::Job |
| 261 : public base::RefCountedThreadSafe<HostResolverImpl::Job> { | 315 : public base::RefCountedThreadSafe<HostResolverImpl::Job> { |
| 262 public: | 316 public: |
| 263 Job(int id, HostResolverImpl* resolver, const Key& key) | 317 Job(int id, |
| 264 : id_(id), | 318 HostResolverImpl* resolver, |
| 265 key_(key), | 319 const Key& key, |
| 266 resolver_(resolver), | 320 const BoundNetLog& source_net_log, |
| 267 origin_loop_(MessageLoop::current()), | 321 NetLog* net_log) |
| 268 resolver_proc_(resolver->effective_resolver_proc()), | 322 : id_(id), |
| 269 error_(OK), | 323 key_(key), |
| 270 os_error_(0), | 324 resolver_(resolver), |
| 271 had_non_speculative_request_(false) { | 325 origin_loop_(MessageLoop::current()), |
| 326 resolver_proc_(resolver->effective_resolver_proc()), |
| 327 error_(OK), |
| 328 os_error_(0), |
| 329 had_non_speculative_request_(false), |
| 330 net_log_(BoundNetLog::Make(net_log, |
| 331 NetLog::SOURCE_HOST_RESOLVER_IMPL_JOB)) { |
| 332 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, |
| 333 new JobCreationParameters(key.hostname, |
| 334 source_net_log.source())); |
| 272 } | 335 } |
| 273 | 336 |
| 274 // Attaches a request to this job. The job takes ownership of |req| and will | 337 // Attaches a request to this job. The job takes ownership of |req| and will |
| 275 // take care to delete it. | 338 // take care to delete it. |
| 276 void AddRequest(Request* req) { | 339 void AddRequest(Request* req) { |
| 340 req->request_net_log().BeginEvent( |
| 341 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_ATTACH, |
| 342 new NetLogSourceParameter("source_dependency", net_log_.source())); |
| 343 |
| 277 req->set_job(this); | 344 req->set_job(this); |
| 278 requests_.push_back(req); | 345 requests_.push_back(req); |
| 279 | 346 |
| 280 if (!req->info().is_speculative()) | 347 if (!req->info().is_speculative()) |
| 281 had_non_speculative_request_ = true; | 348 had_non_speculative_request_ = true; |
| 282 } | 349 } |
| 283 | 350 |
| 284 // Called from origin loop. | 351 // Called from origin loop. |
| 285 void Start() { | 352 void Start() { |
| 286 start_time_ = base::TimeTicks::Now(); | 353 start_time_ = base::TimeTicks::Now(); |
| 287 | 354 |
| 288 // Dispatch the job to a worker thread. | 355 // Dispatch the job to a worker thread. |
| 289 if (!WorkerPool::PostTask(FROM_HERE, | 356 if (!WorkerPool::PostTask(FROM_HERE, |
| 290 NewRunnableMethod(this, &Job::DoLookup), true)) { | 357 NewRunnableMethod(this, &Job::DoLookup), true)) { |
| 291 NOTREACHED(); | 358 NOTREACHED(); |
| 292 | 359 |
| 293 // Since we could be running within Resolve() right now, we can't just | 360 // Since we could be running within Resolve() right now, we can't just |
| 294 // call OnLookupComplete(). Instead we must wait until Resolve() has | 361 // call OnLookupComplete(). Instead we must wait until Resolve() has |
| 295 // returned (IO_PENDING). | 362 // returned (IO_PENDING). |
| 296 error_ = ERR_UNEXPECTED; | 363 error_ = ERR_UNEXPECTED; |
| 297 MessageLoop::current()->PostTask( | 364 MessageLoop::current()->PostTask( |
| 298 FROM_HERE, NewRunnableMethod(this, &Job::OnLookupComplete)); | 365 FROM_HERE, NewRunnableMethod(this, &Job::OnLookupComplete)); |
| 299 } | 366 } |
| 300 } | 367 } |
| 301 | 368 |
| 302 // Cancels the current job. Callable from origin thread. | 369 // Cancels the current job. Callable from origin thread. |
| 303 void Cancel() { | 370 void Cancel() { |
| 371 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL); |
| 372 |
| 304 HostResolver* resolver = resolver_; | 373 HostResolver* resolver = resolver_; |
| 305 resolver_ = NULL; | 374 resolver_ = NULL; |
| 306 | 375 |
| 307 // Mark the job as cancelled, so when worker thread completes it will | 376 // Mark the job as cancelled, so when worker thread completes it will |
| 308 // not try to post completion to origin loop. | 377 // not try to post completion to origin loop. |
| 309 { | 378 { |
| 310 AutoLock locked(origin_loop_lock_); | 379 AutoLock locked(origin_loop_lock_); |
| 311 origin_loop_ = NULL; | 380 origin_loop_ = NULL; |
| 312 } | 381 } |
| 313 | 382 |
| 383 // End here to prevent issues when a Job outlives the HostResolver that |
| 384 // spawned it. |
| 385 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, NULL); |
| 386 |
| 314 // We will call HostResolverImpl::CancelRequest(Request*) on each one | 387 // We will call HostResolverImpl::CancelRequest(Request*) on each one |
| 315 // in order to notify any observers. | 388 // in order to notify any observers. |
| 316 for (RequestsList::const_iterator it = requests_.begin(); | 389 for (RequestsList::const_iterator it = requests_.begin(); |
| 317 it != requests_.end(); ++it) { | 390 it != requests_.end(); ++it) { |
| 318 HostResolverImpl::Request* req = *it; | 391 HostResolverImpl::Request* req = *it; |
| 319 if (!req->was_cancelled()) | 392 if (!req->was_cancelled()) |
| 320 resolver->CancelRequest(req); | 393 resolver->CancelRequest(req); |
| 321 } | 394 } |
| 322 } | 395 } |
| 323 | 396 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 | 478 |
| 406 if (error_ != OK) { | 479 if (error_ != OK) { |
| 407 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.OSErrorsForGetAddrinfo", | 480 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.OSErrorsForGetAddrinfo", |
| 408 std::abs(os_error_), | 481 std::abs(os_error_), |
| 409 GetAllGetAddrinfoOSErrors()); | 482 GetAllGetAddrinfoOSErrors()); |
| 410 } | 483 } |
| 411 | 484 |
| 412 if (was_cancelled()) | 485 if (was_cancelled()) |
| 413 return; | 486 return; |
| 414 | 487 |
| 488 scoped_refptr<NetLog::EventParameters> params; |
| 489 if (error_ != OK) { |
| 490 params = new HostResolveFailedParams(error_, os_error_); |
| 491 } else { |
| 492 params = new AddressListNetLogParam(results_); |
| 493 } |
| 494 |
| 495 // End here to prevent issues when a Job outlives the HostResolver that |
| 496 // spawned it. |
| 497 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, params); |
| 498 |
| 415 DCHECK(!requests_.empty()); | 499 DCHECK(!requests_.empty()); |
| 416 | 500 |
| 417 // Use the port number of the first request. | 501 // Use the port number of the first request. |
| 418 if (error_ == OK) | 502 if (error_ == OK) |
| 419 results_.SetPort(requests_[0]->port()); | 503 results_.SetPort(requests_[0]->port()); |
| 420 | 504 |
| 421 resolver_->OnJobComplete(this, error_, os_error_, results_); | 505 resolver_->OnJobComplete(this, error_, os_error_, results_); |
| 422 } | 506 } |
| 423 | 507 |
| 424 // Immutable. Can be read from either thread, | 508 // Immutable. Can be read from either thread, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 449 // (regardless of whether or not it was later cancelled. | 533 // (regardless of whether or not it was later cancelled. |
| 450 // This boolean is used for histogramming the duration of jobs used to | 534 // This boolean is used for histogramming the duration of jobs used to |
| 451 // service non-speculative requests. | 535 // service non-speculative requests. |
| 452 bool had_non_speculative_request_; | 536 bool had_non_speculative_request_; |
| 453 | 537 |
| 454 AddressList results_; | 538 AddressList results_; |
| 455 | 539 |
| 456 // The time when the job was started. | 540 // The time when the job was started. |
| 457 base::TimeTicks start_time_; | 541 base::TimeTicks start_time_; |
| 458 | 542 |
| 543 BoundNetLog net_log_; |
| 544 |
| 459 DISALLOW_COPY_AND_ASSIGN(Job); | 545 DISALLOW_COPY_AND_ASSIGN(Job); |
| 460 }; | 546 }; |
| 461 | 547 |
| 462 //----------------------------------------------------------------------------- | 548 //----------------------------------------------------------------------------- |
| 463 | 549 |
| 464 // This class represents a request to the worker pool for a "probe for IPv6 | 550 // This class represents a request to the worker pool for a "probe for IPv6 |
| 465 // support" call. | 551 // support" call. |
| 466 class HostResolverImpl::IPv6ProbeJob | 552 class HostResolverImpl::IPv6ProbeJob |
| 467 : public base::RefCountedThreadSafe<HostResolverImpl::IPv6ProbeJob> { | 553 : public base::RefCountedThreadSafe<HostResolverImpl::IPv6ProbeJob> { |
| 468 public: | 554 public: |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 | 687 |
| 602 bool HasPendingRequests() const { | 688 bool HasPendingRequests() const { |
| 603 return GetNumPendingRequests() > 0u; | 689 return GetNumPendingRequests() > 0u; |
| 604 } | 690 } |
| 605 | 691 |
| 606 // Enqueues a request to this pool. As a result of enqueing this request, | 692 // Enqueues a request to this pool. As a result of enqueing this request, |
| 607 // the queue may have reached its maximum size. In this case, a request is | 693 // the queue may have reached its maximum size. In this case, a request is |
| 608 // evicted from the queue, and returned. Otherwise returns NULL. The caller | 694 // evicted from the queue, and returned. Otherwise returns NULL. The caller |
| 609 // is responsible for freeing the evicted request. | 695 // is responsible for freeing the evicted request. |
| 610 Request* InsertPendingRequest(Request* req) { | 696 Request* InsertPendingRequest(Request* req) { |
| 697 req->request_net_log().BeginEvent( |
| 698 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_POOL_QUEUE, |
| 699 NULL); |
| 700 |
| 611 PendingRequestsQueue& q = pending_requests_[req->info().priority()]; | 701 PendingRequestsQueue& q = pending_requests_[req->info().priority()]; |
| 612 q.push_back(req); | 702 q.push_back(req); |
| 613 | 703 |
| 614 // If the queue is too big, kick out the lowest priority oldest request. | 704 // If the queue is too big, kick out the lowest priority oldest request. |
| 615 if (GetNumPendingRequests() > max_pending_requests_) { | 705 if (GetNumPendingRequests() > max_pending_requests_) { |
| 616 // Iterate over the queues from lowest priority to highest priority. | 706 // Iterate over the queues from lowest priority to highest priority. |
| 617 for (int i = static_cast<int>(arraysize(pending_requests_)) - 1; | 707 for (int i = static_cast<int>(arraysize(pending_requests_)) - 1; |
| 618 i >= 0; --i) { | 708 i >= 0; --i) { |
| 619 PendingRequestsQueue& q = pending_requests_[i]; | 709 PendingRequestsQueue& q = pending_requests_[i]; |
| 620 if (!q.empty()) { | 710 if (!q.empty()) { |
| 621 Request* req = q.front(); | 711 Request* req = q.front(); |
| 622 q.pop_front(); | 712 q.pop_front(); |
| 713 req->request_net_log().AddEvent( |
| 714 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_POOL_QUEUE_EVICTED, NULL); |
| 715 req->request_net_log().EndEvent( |
| 716 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_POOL_QUEUE, NULL); |
| 623 return req; | 717 return req; |
| 624 } | 718 } |
| 625 } | 719 } |
| 626 } | 720 } |
| 627 | 721 |
| 628 return NULL; | 722 return NULL; |
| 629 } | 723 } |
| 630 | 724 |
| 631 // Erases |req| from this container. Caller is responsible for freeing | 725 // Erases |req| from this container. Caller is responsible for freeing |
| 632 // |req| afterwards. | 726 // |req| afterwards. |
| 633 void RemovePendingRequest(Request* req) { | 727 void RemovePendingRequest(Request* req) { |
| 634 PendingRequestsQueue& q = pending_requests_[req->info().priority()]; | 728 PendingRequestsQueue& q = pending_requests_[req->info().priority()]; |
| 635 PendingRequestsQueue::iterator it = std::find(q.begin(), q.end(), req); | 729 PendingRequestsQueue::iterator it = std::find(q.begin(), q.end(), req); |
| 636 DCHECK(it != q.end()); | 730 DCHECK(it != q.end()); |
| 637 q.erase(it); | 731 q.erase(it); |
| 732 req->request_net_log().EndEvent( |
| 733 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_POOL_QUEUE, NULL); |
| 638 } | 734 } |
| 639 | 735 |
| 640 // Removes and returns the highest priority pending request. | 736 // Removes and returns the highest priority pending request. |
| 641 Request* RemoveTopPendingRequest() { | 737 Request* RemoveTopPendingRequest() { |
| 642 DCHECK(HasPendingRequests()); | 738 DCHECK(HasPendingRequests()); |
| 643 | 739 |
| 644 for (size_t i = 0u; i < arraysize(pending_requests_); ++i) { | 740 for (size_t i = 0u; i < arraysize(pending_requests_); ++i) { |
| 645 PendingRequestsQueue& q = pending_requests_[i]; | 741 PendingRequestsQueue& q = pending_requests_[i]; |
| 646 if (!q.empty()) { | 742 if (!q.empty()) { |
| 647 Request* req = q.front(); | 743 Request* req = q.front(); |
| 648 q.pop_front(); | 744 q.pop_front(); |
| 745 req->request_net_log().EndEvent( |
| 746 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_POOL_QUEUE, NULL); |
| 649 return req; | 747 return req; |
| 650 } | 748 } |
| 651 } | 749 } |
| 652 | 750 |
| 653 NOTREACHED(); | 751 NOTREACHED(); |
| 654 return NULL; | 752 return NULL; |
| 655 } | 753 } |
| 656 | 754 |
| 657 // Keeps track of a job that was just added/removed, and belongs to this pool. | 755 // Keeps track of a job that was just added/removed, and belongs to this pool. |
| 658 void AdjustNumOutstandingJobs(int offset) { | 756 void AdjustNumOutstandingJobs(int offset) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 | 800 |
| 703 // The requests which are waiting to be started for this pool. | 801 // The requests which are waiting to be started for this pool. |
| 704 PendingRequestsQueue pending_requests_[NUM_PRIORITIES]; | 802 PendingRequestsQueue pending_requests_[NUM_PRIORITIES]; |
| 705 }; | 803 }; |
| 706 | 804 |
| 707 //----------------------------------------------------------------------------- | 805 //----------------------------------------------------------------------------- |
| 708 | 806 |
| 709 HostResolverImpl::HostResolverImpl( | 807 HostResolverImpl::HostResolverImpl( |
| 710 HostResolverProc* resolver_proc, | 808 HostResolverProc* resolver_proc, |
| 711 HostCache* cache, | 809 HostCache* cache, |
| 712 size_t max_jobs) | 810 size_t max_jobs, |
| 811 NetLog* net_log) |
| 713 : cache_(cache), | 812 : cache_(cache), |
| 714 max_jobs_(max_jobs), | 813 max_jobs_(max_jobs), |
| 715 next_request_id_(0), | 814 next_request_id_(0), |
| 716 next_job_id_(0), | 815 next_job_id_(0), |
| 717 resolver_proc_(resolver_proc), | 816 resolver_proc_(resolver_proc), |
| 718 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), | 817 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), |
| 719 shutdown_(false), | 818 shutdown_(false), |
| 720 ipv6_probe_monitoring_(false), | 819 ipv6_probe_monitoring_(false), |
| 721 additional_resolver_flags_(0) { | 820 additional_resolver_flags_(0), |
| 821 net_log_(net_log) { |
| 722 DCHECK_GT(max_jobs, 0u); | 822 DCHECK_GT(max_jobs, 0u); |
| 723 | 823 |
| 724 // It is cumbersome to expose all of the constraints in the constructor, | 824 // It is cumbersome to expose all of the constraints in the constructor, |
| 725 // so we choose some defaults, which users can override later. | 825 // so we choose some defaults, which users can override later. |
| 726 job_pools_[POOL_NORMAL] = new JobPool(max_jobs, 100u * max_jobs); | 826 job_pools_[POOL_NORMAL] = new JobPool(max_jobs, 100u * max_jobs); |
| 727 | 827 |
| 728 #if defined(OS_WIN) | 828 #if defined(OS_WIN) |
| 729 EnsureWinsockInit(); | 829 EnsureWinsockInit(); |
| 730 #endif | 830 #endif |
| 731 #if defined(OS_LINUX) | 831 #if defined(OS_LINUX) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 751 | 851 |
| 752 // Delete the job pools. | 852 // Delete the job pools. |
| 753 for (size_t i = 0u; i < arraysize(job_pools_); ++i) | 853 for (size_t i = 0u; i < arraysize(job_pools_); ++i) |
| 754 delete job_pools_[i]; | 854 delete job_pools_[i]; |
| 755 } | 855 } |
| 756 | 856 |
| 757 int HostResolverImpl::Resolve(const RequestInfo& info, | 857 int HostResolverImpl::Resolve(const RequestInfo& info, |
| 758 AddressList* addresses, | 858 AddressList* addresses, |
| 759 CompletionCallback* callback, | 859 CompletionCallback* callback, |
| 760 RequestHandle* out_req, | 860 RequestHandle* out_req, |
| 761 const BoundNetLog& net_log) { | 861 const BoundNetLog& source_net_log) { |
| 762 DCHECK(CalledOnValidThread()); | 862 DCHECK(CalledOnValidThread()); |
| 763 | 863 |
| 764 if (shutdown_) | 864 if (shutdown_) |
| 765 return ERR_UNEXPECTED; | 865 return ERR_UNEXPECTED; |
| 766 | 866 |
| 767 // Choose a unique ID number for observers to see. | 867 // Choose a unique ID number for observers to see. |
| 768 int request_id = next_request_id_++; | 868 int request_id = next_request_id_++; |
| 769 | 869 |
| 870 // Make a log item for the request. |
| 871 BoundNetLog request_net_log = BoundNetLog::Make(net_log_, |
| 872 NetLog::SOURCE_HOST_RESOLVER_IMPL_REQUEST); |
| 873 |
| 770 // Update the net log and notify registered observers. | 874 // Update the net log and notify registered observers. |
| 771 OnStartRequest(net_log, request_id, info); | 875 OnStartRequest(source_net_log, request_net_log, request_id, info); |
| 772 | 876 |
| 773 // Check for IP literal. | 877 // Check for IP literal. |
| 774 IPAddressNumber ip_number; | 878 IPAddressNumber ip_number; |
| 775 if (ParseIPLiteralToNumber(info.hostname(), &ip_number)) { | 879 if (ParseIPLiteralToNumber(info.hostname(), &ip_number)) { |
| 776 DCHECK_EQ((info.host_resolver_flags() & | 880 DCHECK_EQ((info.host_resolver_flags() & |
| 777 ~(HOST_RESOLVER_CANONNAME | HOST_RESOLVER_LOOPBACK_ONLY)), 0) | 881 ~(HOST_RESOLVER_CANONNAME | HOST_RESOLVER_LOOPBACK_ONLY)), 0) |
| 778 << " Unhandled flag"; | 882 << " Unhandled flag"; |
| 779 AddressList result(ip_number, info.port(), | 883 AddressList result(ip_number, info.port(), |
| 780 (info.host_resolver_flags() & HOST_RESOLVER_CANONNAME)); | 884 (info.host_resolver_flags() & HOST_RESOLVER_CANONNAME)); |
| 781 | 885 |
| 782 *addresses = result; | 886 *addresses = result; |
| 783 // Update the net log and notify registered observers. | 887 // Update the net log and notify registered observers. |
| 784 OnFinishRequest(net_log, request_id, info, OK, | 888 OnFinishRequest(source_net_log, request_net_log, request_id, info, OK, |
| 785 0, /* os_error (unknown since from cache) */ | 889 0 /* os_error (unknown since from cache) */); |
| 786 false /* was_from_cache */); | |
| 787 return OK; | 890 return OK; |
| 788 } | 891 } |
| 789 | 892 |
| 790 // Build a key that identifies the request in the cache and in the | 893 // Build a key that identifies the request in the cache and in the |
| 791 // outstanding jobs map. | 894 // outstanding jobs map. |
| 792 Key key = GetEffectiveKeyForRequest(info); | 895 Key key = GetEffectiveKeyForRequest(info); |
| 793 | 896 |
| 794 // If we have an unexpired cache entry, use it. | 897 // If we have an unexpired cache entry, use it. |
| 795 if (info.allow_cached_response() && cache_.get()) { | 898 if (info.allow_cached_response() && cache_.get()) { |
| 796 const HostCache::Entry* cache_entry = cache_->Lookup( | 899 const HostCache::Entry* cache_entry = cache_->Lookup( |
| 797 key, base::TimeTicks::Now()); | 900 key, base::TimeTicks::Now()); |
| 798 if (cache_entry) { | 901 if (cache_entry) { |
| 902 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT, NULL); |
| 799 int net_error = cache_entry->error; | 903 int net_error = cache_entry->error; |
| 800 if (net_error == OK) | 904 if (net_error == OK) |
| 801 addresses->SetFrom(cache_entry->addrlist, info.port()); | 905 addresses->SetFrom(cache_entry->addrlist, info.port()); |
| 802 | 906 |
| 803 // Update the net log and notify registered observers. | 907 // Update the net log and notify registered observers. |
| 804 OnFinishRequest(net_log, request_id, info, net_error, | 908 OnFinishRequest(source_net_log, request_net_log, request_id, info, |
| 805 0, /* os_error (unknown since from cache) */ | 909 net_error, |
| 806 true /* was_from_cache */); | 910 0 /* os_error (unknown since from cache) */); |
| 807 | 911 |
| 808 return net_error; | 912 return net_error; |
| 809 } | 913 } |
| 810 } | 914 } |
| 811 | 915 |
| 812 // If no callback was specified, do a synchronous resolution. | 916 // If no callback was specified, do a synchronous resolution. |
| 813 if (!callback) { | 917 if (!callback) { |
| 814 AddressList addrlist; | 918 AddressList addrlist; |
| 815 int os_error = 0; | 919 int os_error = 0; |
| 816 int error = ResolveAddrInfo( | 920 int error = ResolveAddrInfo( |
| 817 effective_resolver_proc(), key.hostname, key.address_family, | 921 effective_resolver_proc(), key.hostname, key.address_family, |
| 818 key.host_resolver_flags, &addrlist, &os_error); | 922 key.host_resolver_flags, &addrlist, &os_error); |
| 819 if (error == OK) { | 923 if (error == OK) { |
| 820 addrlist.SetPort(info.port()); | 924 addrlist.SetPort(info.port()); |
| 821 *addresses = addrlist; | 925 *addresses = addrlist; |
| 822 } | 926 } |
| 823 | 927 |
| 824 // Write to cache. | 928 // Write to cache. |
| 825 if (cache_.get()) | 929 if (cache_.get()) |
| 826 cache_->Set(key, error, addrlist, base::TimeTicks::Now()); | 930 cache_->Set(key, error, addrlist, base::TimeTicks::Now()); |
| 827 | 931 |
| 828 // Update the net log and notify registered observers. | 932 // Update the net log and notify registered observers. |
| 829 OnFinishRequest(net_log, request_id, info, error, os_error, | 933 OnFinishRequest(source_net_log, request_net_log, request_id, info, error, |
| 830 false /* was_from_cache */); | 934 os_error); |
| 831 | 935 |
| 832 return error; | 936 return error; |
| 833 } | 937 } |
| 834 | 938 |
| 835 // Create a handle for this request, and pass it back to the user if they | 939 // Create a handle for this request, and pass it back to the user if they |
| 836 // asked for it (out_req != NULL). | 940 // asked for it (out_req != NULL). |
| 837 Request* req = new Request(net_log, request_id, info, callback, addresses); | 941 Request* req = new Request(source_net_log, request_net_log, request_id, info, |
| 942 callback, addresses); |
| 838 if (out_req) | 943 if (out_req) |
| 839 *out_req = reinterpret_cast<RequestHandle>(req); | 944 *out_req = reinterpret_cast<RequestHandle>(req); |
| 840 | 945 |
| 841 // Next we need to attach our request to a "job". This job is responsible for | 946 // Next we need to attach our request to a "job". This job is responsible for |
| 842 // calling "getaddrinfo(hostname)" on a worker thread. | 947 // calling "getaddrinfo(hostname)" on a worker thread. |
| 843 scoped_refptr<Job> job; | 948 scoped_refptr<Job> job; |
| 844 | 949 |
| 845 // If there is already an outstanding job to resolve |key|, use | 950 // If there is already an outstanding job to resolve |key|, use |
| 846 // it. This prevents starting concurrent resolves for the same hostname. | 951 // it. This prevents starting concurrent resolves for the same hostname. |
| 847 job = FindOutstandingJob(key); | 952 job = FindOutstandingJob(key); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 878 scoped_ptr<Request> request_deleter; // Frees at end of function. | 983 scoped_ptr<Request> request_deleter; // Frees at end of function. |
| 879 | 984 |
| 880 if (!req->job()) { | 985 if (!req->job()) { |
| 881 // If the request was not attached to a job yet, it must have been | 986 // If the request was not attached to a job yet, it must have been |
| 882 // enqueued into a pool. Remove it from that pool's queue. | 987 // enqueued into a pool. Remove it from that pool's queue. |
| 883 // Otherwise if it was attached to a job, the job is responsible for | 988 // Otherwise if it was attached to a job, the job is responsible for |
| 884 // deleting it. | 989 // deleting it. |
| 885 JobPool* pool = GetPoolForRequest(req); | 990 JobPool* pool = GetPoolForRequest(req); |
| 886 pool->RemovePendingRequest(req); | 991 pool->RemovePendingRequest(req); |
| 887 request_deleter.reset(req); | 992 request_deleter.reset(req); |
| 993 } else { |
| 994 req->request_net_log().EndEvent( |
| 995 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_ATTACH, NULL); |
| 888 } | 996 } |
| 889 | 997 |
| 890 // NULL out the fields of req, to mark it as cancelled. | 998 // NULL out the fields of req, to mark it as cancelled. |
| 891 req->MarkAsCancelled(); | 999 req->MarkAsCancelled(); |
| 892 OnCancelRequest(req->net_log(), req->id(), req->info()); | 1000 OnCancelRequest(req->source_net_log(), req->request_net_log(), req->id(), |
| 1001 req->info()); |
| 893 } | 1002 } |
| 894 | 1003 |
| 895 void HostResolverImpl::AddObserver(HostResolver::Observer* observer) { | 1004 void HostResolverImpl::AddObserver(HostResolver::Observer* observer) { |
| 896 DCHECK(CalledOnValidThread()); | 1005 DCHECK(CalledOnValidThread()); |
| 897 observers_.push_back(observer); | 1006 observers_.push_back(observer); |
| 898 } | 1007 } |
| 899 | 1008 |
| 900 void HostResolverImpl::RemoveObserver(HostResolver::Observer* observer) { | 1009 void HostResolverImpl::RemoveObserver(HostResolver::Observer* observer) { |
| 901 DCHECK(CalledOnValidThread()); | 1010 DCHECK(CalledOnValidThread()); |
| 902 ObserversList::iterator it = | 1011 ObserversList::iterator it = |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 988 | 1097 |
| 989 // Try to start any queued requests now that a job-slot has freed up. | 1098 // Try to start any queued requests now that a job-slot has freed up. |
| 990 ProcessQueuedRequests(); | 1099 ProcessQueuedRequests(); |
| 991 | 1100 |
| 992 // Complete all of the requests that were attached to the job. | 1101 // Complete all of the requests that were attached to the job. |
| 993 for (RequestsList::const_iterator it = job->requests().begin(); | 1102 for (RequestsList::const_iterator it = job->requests().begin(); |
| 994 it != job->requests().end(); ++it) { | 1103 it != job->requests().end(); ++it) { |
| 995 Request* req = *it; | 1104 Request* req = *it; |
| 996 if (!req->was_cancelled()) { | 1105 if (!req->was_cancelled()) { |
| 997 DCHECK_EQ(job, req->job()); | 1106 DCHECK_EQ(job, req->job()); |
| 1107 req->request_net_log().EndEvent( |
| 1108 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_ATTACH, NULL); |
| 998 | 1109 |
| 999 // Update the net log and notify registered observers. | 1110 // Update the net log and notify registered observers. |
| 1000 OnFinishRequest(req->net_log(), req->id(), req->info(), net_error, | 1111 OnFinishRequest(req->source_net_log(), req->request_net_log(), req->id(), |
| 1001 os_error, false /* was_from_cache */); | 1112 req->info(), net_error, os_error); |
| 1002 | 1113 |
| 1003 req->OnComplete(net_error, addrlist); | 1114 req->OnComplete(net_error, addrlist); |
| 1004 | 1115 |
| 1005 // Check if the job was cancelled as a result of running the callback. | 1116 // Check if the job was cancelled as a result of running the callback. |
| 1006 // (Meaning that |this| was deleted). | 1117 // (Meaning that |this| was deleted). |
| 1007 if (job->was_cancelled()) | 1118 if (job->was_cancelled()) |
| 1008 return; | 1119 return; |
| 1009 } | 1120 } |
| 1010 } | 1121 } |
| 1011 | 1122 |
| 1012 cur_completing_job_ = NULL; | 1123 cur_completing_job_ = NULL; |
| 1013 } | 1124 } |
| 1014 | 1125 |
| 1015 void HostResolverImpl::OnStartRequest(const BoundNetLog& net_log, | 1126 void HostResolverImpl::OnStartRequest(const BoundNetLog& source_net_log, |
| 1127 const BoundNetLog& request_net_log, |
| 1016 int request_id, | 1128 int request_id, |
| 1017 const RequestInfo& info) { | 1129 const RequestInfo& info) { |
| 1018 net_log.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, NULL); | 1130 source_net_log.BeginEvent( |
| 1131 NetLog::TYPE_HOST_RESOLVER_IMPL, |
| 1132 new NetLogSourceParameter("source_dependency", request_net_log.source())); |
| 1133 |
| 1134 request_net_log.BeginEvent( |
| 1135 NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, |
| 1136 new RequestInfoParameters(info, source_net_log.source())); |
| 1019 | 1137 |
| 1020 // Notify the observers of the start. | 1138 // Notify the observers of the start. |
| 1021 if (!observers_.empty()) { | 1139 if (!observers_.empty()) { |
| 1022 for (ObserversList::iterator it = observers_.begin(); | 1140 for (ObserversList::iterator it = observers_.begin(); |
| 1023 it != observers_.end(); ++it) { | 1141 it != observers_.end(); ++it) { |
| 1024 (*it)->OnStartResolution(request_id, info); | 1142 (*it)->OnStartResolution(request_id, info); |
| 1025 } | 1143 } |
| 1026 } | 1144 } |
| 1027 } | 1145 } |
| 1028 | 1146 |
| 1029 void HostResolverImpl::OnFinishRequest(const BoundNetLog& net_log, | 1147 void HostResolverImpl::OnFinishRequest(const BoundNetLog& source_net_log, |
| 1148 const BoundNetLog& request_net_log, |
| 1030 int request_id, | 1149 int request_id, |
| 1031 const RequestInfo& info, | 1150 const RequestInfo& info, |
| 1032 int net_error, | 1151 int net_error, |
| 1033 int os_error, | 1152 int os_error) { |
| 1034 bool was_from_cache) { | |
| 1035 bool was_resolved = net_error == OK; | 1153 bool was_resolved = net_error == OK; |
| 1036 | 1154 |
| 1037 // Notify the observers of the completion. | 1155 // Notify the observers of the completion. |
| 1038 if (!observers_.empty()) { | 1156 if (!observers_.empty()) { |
| 1039 for (ObserversList::iterator it = observers_.begin(); | 1157 for (ObserversList::iterator it = observers_.begin(); |
| 1040 it != observers_.end(); ++it) { | 1158 it != observers_.end(); ++it) { |
| 1041 (*it)->OnFinishResolutionWithStatus(request_id, was_resolved, info); | 1159 (*it)->OnFinishResolutionWithStatus(request_id, was_resolved, info); |
| 1042 } | 1160 } |
| 1043 } | 1161 } |
| 1044 | 1162 |
| 1045 // Log some extra parameters on failure. | 1163 // Log some extra parameters on failure for synchronous requests. |
| 1046 scoped_refptr<NetLog::EventParameters> params; | 1164 scoped_refptr<NetLog::EventParameters> params; |
| 1047 if (!was_resolved) | 1165 if (!was_resolved) { |
| 1048 params = new HostResolveFailedParams(net_error, os_error, was_from_cache); | 1166 params = new HostResolveFailedParams(net_error, os_error); |
| 1167 } |
| 1049 | 1168 |
| 1050 net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, params); | 1169 request_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, params); |
| 1170 source_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, NULL); |
| 1051 } | 1171 } |
| 1052 | 1172 |
| 1053 void HostResolverImpl::OnCancelRequest(const BoundNetLog& net_log, | 1173 void HostResolverImpl::OnCancelRequest(const BoundNetLog& source_net_log, |
| 1174 const BoundNetLog& request_net_log, |
| 1054 int request_id, | 1175 int request_id, |
| 1055 const RequestInfo& info) { | 1176 const RequestInfo& info) { |
| 1056 net_log.AddEvent(NetLog::TYPE_CANCELLED, NULL); | 1177 request_net_log.AddEvent(NetLog::TYPE_CANCELLED, NULL); |
| 1057 | 1178 |
| 1058 // Notify the observers of the cancellation. | 1179 // Notify the observers of the cancellation. |
| 1059 if (!observers_.empty()) { | 1180 if (!observers_.empty()) { |
| 1060 for (ObserversList::iterator it = observers_.begin(); | 1181 for (ObserversList::iterator it = observers_.begin(); |
| 1061 it != observers_.end(); ++it) { | 1182 it != observers_.end(); ++it) { |
| 1062 (*it)->OnCancelResolution(request_id, info); | 1183 (*it)->OnCancelResolution(request_id, info); |
| 1063 } | 1184 } |
| 1064 } | 1185 } |
| 1065 | 1186 |
| 1066 net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, NULL); | 1187 request_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, NULL); |
| 1188 source_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, NULL); |
| 1067 } | 1189 } |
| 1068 | 1190 |
| 1069 void HostResolverImpl::OnIPAddressChanged() { | 1191 void HostResolverImpl::OnIPAddressChanged() { |
| 1070 if (cache_.get()) | 1192 if (cache_.get()) |
| 1071 cache_->clear(); | 1193 cache_->clear(); |
| 1072 if (ipv6_probe_monitoring_) { | 1194 if (ipv6_probe_monitoring_) { |
| 1073 DCHECK(!shutdown_); | 1195 DCHECK(!shutdown_); |
| 1074 if (shutdown_) | 1196 if (shutdown_) |
| 1075 return; | 1197 return; |
| 1076 DiscardIPv6ProbeJob(); | 1198 DiscardIPv6ProbeJob(); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1153 AddressFamily effective_address_family = info.address_family(); | 1275 AddressFamily effective_address_family = info.address_family(); |
| 1154 if (effective_address_family == ADDRESS_FAMILY_UNSPECIFIED) | 1276 if (effective_address_family == ADDRESS_FAMILY_UNSPECIFIED) |
| 1155 effective_address_family = default_address_family_; | 1277 effective_address_family = default_address_family_; |
| 1156 return Key(info.hostname(), effective_address_family, | 1278 return Key(info.hostname(), effective_address_family, |
| 1157 info.host_resolver_flags() | additional_resolver_flags_); | 1279 info.host_resolver_flags() | additional_resolver_flags_); |
| 1158 } | 1280 } |
| 1159 | 1281 |
| 1160 HostResolverImpl::Job* HostResolverImpl::CreateAndStartJob(Request* req) { | 1282 HostResolverImpl::Job* HostResolverImpl::CreateAndStartJob(Request* req) { |
| 1161 DCHECK(CanCreateJobForPool(*GetPoolForRequest(req))); | 1283 DCHECK(CanCreateJobForPool(*GetPoolForRequest(req))); |
| 1162 Key key = GetEffectiveKeyForRequest(req->info()); | 1284 Key key = GetEffectiveKeyForRequest(req->info()); |
| 1163 scoped_refptr<Job> job = new Job(next_job_id_++, this, key); | 1285 |
| 1286 req->request_net_log().AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CREATE_JOB, |
| 1287 NULL); |
| 1288 |
| 1289 scoped_refptr<Job> job = new Job(next_job_id_++, this, key, |
| 1290 req->request_net_log(), net_log_); |
| 1164 job->AddRequest(req); | 1291 job->AddRequest(req); |
| 1165 AddOutstandingJob(job); | 1292 AddOutstandingJob(job); |
| 1166 job->Start(); | 1293 job->Start(); |
| 1294 |
| 1167 return job.get(); | 1295 return job.get(); |
| 1168 } | 1296 } |
| 1169 | 1297 |
| 1170 int HostResolverImpl::EnqueueRequest(JobPool* pool, Request* req) { | 1298 int HostResolverImpl::EnqueueRequest(JobPool* pool, Request* req) { |
| 1171 scoped_ptr<Request> req_evicted_from_queue( | 1299 scoped_ptr<Request> req_evicted_from_queue( |
| 1172 pool->InsertPendingRequest(req)); | 1300 pool->InsertPendingRequest(req)); |
| 1173 | 1301 |
| 1174 // If the queue has become too large, we need to kick something out. | 1302 // If the queue has become too large, we need to kick something out. |
| 1175 if (req_evicted_from_queue.get()) { | 1303 if (req_evicted_from_queue.get()) { |
| 1176 Request* r = req_evicted_from_queue.get(); | 1304 Request* r = req_evicted_from_queue.get(); |
| 1177 int error = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE; | 1305 int error = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE; |
| 1178 | 1306 |
| 1179 OnFinishRequest(r->net_log(), r->id(), r->info(), error, | 1307 OnFinishRequest(r->source_net_log(), r->request_net_log(), r->id(), |
| 1180 0, /* os_error (not applicable) */ | 1308 r->info(), error, |
| 1181 false /* was_from_cache */); | 1309 0 /* os_error (not applicable) */); |
| 1182 | 1310 |
| 1183 if (r == req) | 1311 if (r == req) |
| 1184 return error; | 1312 return error; |
| 1185 | 1313 |
| 1186 r->OnComplete(error, AddressList()); | 1314 r->OnComplete(error, AddressList()); |
| 1187 } | 1315 } |
| 1188 | 1316 |
| 1189 return ERR_IO_PENDING; | 1317 return ERR_IO_PENDING; |
| 1190 } | 1318 } |
| 1191 | 1319 |
| 1192 } // namespace net | 1320 } // namespace net |
| OLD | NEW |