OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/dns/host_resolver_impl.h" | 5 #include "net/dns/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> |
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
963 | 963 |
964 DISALLOW_COPY_AND_ASSIGN(LoopbackProbeJob); | 964 DISALLOW_COPY_AND_ASSIGN(LoopbackProbeJob); |
965 }; | 965 }; |
966 | 966 |
967 //----------------------------------------------------------------------------- | 967 //----------------------------------------------------------------------------- |
968 | 968 |
969 // Resolves the hostname using DnsTransaction. | 969 // Resolves the hostname using DnsTransaction. |
970 // TODO(szym): This could be moved to separate source file as well. | 970 // TODO(szym): This could be moved to separate source file as well. |
971 class HostResolverImpl::DnsTask : public base::SupportsWeakPtr<DnsTask> { | 971 class HostResolverImpl::DnsTask : public base::SupportsWeakPtr<DnsTask> { |
972 public: | 972 public: |
973 typedef base::Callback<void(int net_error, | 973 class Delegate { |
974 const AddressList& addr_list, | 974 public: |
975 base::TimeDelta ttl)> Callback; | 975 virtual void OnDnsTaskComplete(base::TimeTicks start_time, |
976 int net_error, | |
977 const AddressList& addr_list, | |
978 base::TimeDelta ttl) = 0; | |
979 | |
980 // Called when the first of two jobs succeeds. If the first completed | |
981 // transaction fails, this is not called. Also not called when the DnsTask | |
982 // only needs to run one transaction. | |
983 virtual void OnFirstDnsTransactionComplete() = 0; | |
984 | |
985 protected: | |
986 Delegate() {} | |
987 virtual ~Delegate() {} | |
988 }; | |
976 | 989 |
977 DnsTask(DnsClient* client, | 990 DnsTask(DnsClient* client, |
978 const Key& key, | 991 const Key& key, |
979 const Callback& callback, | 992 Delegate* delegate, |
980 const BoundNetLog& job_net_log) | 993 const BoundNetLog& job_net_log) |
981 : client_(client), | 994 : client_(client), |
982 family_(key.address_family), | 995 key_(key), |
983 callback_(callback), | 996 delegate_(delegate), |
984 net_log_(job_net_log) { | 997 net_log_(job_net_log), |
998 num_completed_transactions_(0), | |
999 task_start_time_(base::TimeTicks::Now()) { | |
985 DCHECK(client); | 1000 DCHECK(client); |
986 DCHECK(!callback.is_null()); | 1001 DCHECK(delegate_); |
1002 } | |
987 | 1003 |
988 // If unspecified, do IPv4 first, because suffix search will be faster. | 1004 bool needs_two_transactions() const { |
989 uint16 qtype = (family_ == ADDRESS_FAMILY_IPV6) ? | 1005 return key_.address_family == ADDRESS_FAMILY_UNSPECIFIED; |
990 dns_protocol::kTypeAAAA : | 1006 } |
991 dns_protocol::kTypeA; | 1007 |
992 transaction_ = client_->GetTransactionFactory()->CreateTransaction( | 1008 bool needs_another_transaction() const { |
993 key.hostname, | 1009 return needs_two_transactions() && !transaction_aaaa_; |
994 qtype, | 1010 } |
1011 | |
1012 void StartFirstTransaction() { | |
1013 DCHECK_EQ(0u, num_completed_transactions_); | |
1014 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK); | |
1015 if (key_.address_family == ADDRESS_FAMILY_IPV6) { | |
1016 StartAAAA(); | |
1017 } else { | |
1018 StartA(); | |
1019 } | |
1020 } | |
1021 | |
1022 void StartSecondTransaction() { | |
1023 DCHECK(needs_two_transactions()); | |
1024 StartAAAA(); | |
1025 } | |
1026 | |
1027 private: | |
1028 void StartA() { | |
1029 DCHECK(!transaction_a_); | |
1030 DCHECK_NE(ADDRESS_FAMILY_IPV6, key_.address_family); | |
1031 transaction_a_ = CreateTransaction(ADDRESS_FAMILY_IPV4); | |
1032 transaction_a_->Start(); | |
1033 } | |
1034 | |
1035 void StartAAAA() { | |
1036 DCHECK(!transaction_aaaa_); | |
1037 DCHECK_NE(ADDRESS_FAMILY_IPV4, key_.address_family); | |
1038 transaction_aaaa_ = CreateTransaction(ADDRESS_FAMILY_IPV6); | |
1039 transaction_aaaa_->Start(); | |
1040 } | |
1041 | |
1042 scoped_ptr<DnsTransaction> CreateTransaction(AddressFamily family) { | |
1043 DCHECK_NE(ADDRESS_FAMILY_UNSPECIFIED, family); | |
1044 return client_->GetTransactionFactory()->CreateTransaction( | |
1045 key_.hostname, | |
1046 family == ADDRESS_FAMILY_IPV6 ? dns_protocol::kTypeAAAA : | |
1047 dns_protocol::kTypeA, | |
995 base::Bind(&DnsTask::OnTransactionComplete, base::Unretained(this), | 1048 base::Bind(&DnsTask::OnTransactionComplete, base::Unretained(this), |
996 true /* first_query */, base::TimeTicks::Now()), | 1049 base::TimeTicks::Now()), |
997 net_log_); | 1050 net_log_); |
998 } | 1051 } |
999 | 1052 |
1000 void Start() { | 1053 void OnTransactionComplete(const base::TimeTicks& start_time, |
1001 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK); | |
1002 transaction_->Start(); | |
1003 } | |
1004 | |
1005 private: | |
1006 void OnTransactionComplete(bool first_query, | |
1007 const base::TimeTicks& start_time, | |
1008 DnsTransaction* transaction, | 1054 DnsTransaction* transaction, |
1009 int net_error, | 1055 int net_error, |
1010 const DnsResponse* response) { | 1056 const DnsResponse* response) { |
1011 DCHECK(transaction); | 1057 DCHECK(transaction); |
1012 base::TimeDelta duration = base::TimeTicks::Now() - start_time; | 1058 base::TimeDelta duration = base::TimeTicks::Now() - start_time; |
1013 // Run |callback_| last since the owning Job will then delete this DnsTask. | |
1014 if (net_error != OK) { | 1059 if (net_error != OK) { |
1015 DNS_HISTOGRAM("AsyncDNS.TransactionFailure", duration); | 1060 DNS_HISTOGRAM("AsyncDNS.TransactionFailure", duration); |
1016 OnFailure(net_error, DnsResponse::DNS_PARSE_OK); | 1061 OnFailure(net_error, DnsResponse::DNS_PARSE_OK); |
1017 return; | 1062 return; |
1018 } | 1063 } |
1019 | 1064 |
1020 CHECK(response); | |
1021 DNS_HISTOGRAM("AsyncDNS.TransactionSuccess", duration); | 1065 DNS_HISTOGRAM("AsyncDNS.TransactionSuccess", duration); |
1022 switch (transaction->GetType()) { | 1066 switch (transaction->GetType()) { |
1023 case dns_protocol::kTypeA: | 1067 case dns_protocol::kTypeA: |
1024 DNS_HISTOGRAM("AsyncDNS.TransactionSuccess_A", duration); | 1068 DNS_HISTOGRAM("AsyncDNS.TransactionSuccess_A", duration); |
1025 break; | 1069 break; |
1026 case dns_protocol::kTypeAAAA: | 1070 case dns_protocol::kTypeAAAA: |
1027 DNS_HISTOGRAM("AsyncDNS.TransactionSuccess_AAAA", duration); | 1071 DNS_HISTOGRAM("AsyncDNS.TransactionSuccess_AAAA", duration); |
1028 break; | 1072 break; |
1029 } | 1073 } |
1074 | |
1030 AddressList addr_list; | 1075 AddressList addr_list; |
1031 base::TimeDelta ttl; | 1076 base::TimeDelta ttl; |
1032 DnsResponse::Result result = response->ParseToAddressList(&addr_list, &ttl); | 1077 DnsResponse::Result result = response->ParseToAddressList(&addr_list, &ttl); |
1033 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.ParseToAddressList", | 1078 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.ParseToAddressList", |
1034 result, | 1079 result, |
1035 DnsResponse::DNS_PARSE_RESULT_MAX); | 1080 DnsResponse::DNS_PARSE_RESULT_MAX); |
1036 if (result != DnsResponse::DNS_PARSE_OK) { | 1081 if (result != DnsResponse::DNS_PARSE_OK) { |
1037 // Fail even if the other query succeeds. | 1082 // Fail even if the other query succeeds. |
1038 OnFailure(ERR_DNS_MALFORMED_RESPONSE, result); | 1083 OnFailure(ERR_DNS_MALFORMED_RESPONSE, result); |
1039 return; | 1084 return; |
1040 } | 1085 } |
1041 | 1086 |
1042 bool needs_sort = false; | 1087 ++num_completed_transactions_; |
1043 if (first_query) { | 1088 if (num_completed_transactions_ == 1) { |
1044 DCHECK(client_->GetConfig()) << | 1089 ttl_ = ttl; |
1045 "Transaction should have been aborted when config changed!"; | |
1046 if (family_ == ADDRESS_FAMILY_IPV6) { | |
1047 needs_sort = (addr_list.size() > 1); | |
1048 } else if (family_ == ADDRESS_FAMILY_UNSPECIFIED) { | |
1049 first_addr_list_ = addr_list; | |
1050 first_ttl_ = ttl; | |
1051 // Use fully-qualified domain name to avoid search. | |
1052 transaction_ = client_->GetTransactionFactory()->CreateTransaction( | |
1053 response->GetDottedName() + ".", | |
1054 dns_protocol::kTypeAAAA, | |
1055 base::Bind(&DnsTask::OnTransactionComplete, base::Unretained(this), | |
1056 false /* first_query */, base::TimeTicks::Now()), | |
1057 net_log_); | |
1058 transaction_->Start(); | |
1059 return; | |
1060 } | |
1061 } else { | 1090 } else { |
1062 DCHECK_EQ(ADDRESS_FAMILY_UNSPECIFIED, family_); | 1091 ttl_ = std::min(ttl_, ttl); |
1063 bool has_ipv6_addresses = !addr_list.empty(); | |
1064 if (!first_addr_list_.empty()) { | |
1065 ttl = std::min(ttl, first_ttl_); | |
1066 // Place IPv4 addresses after IPv6. | |
1067 addr_list.insert(addr_list.end(), first_addr_list_.begin(), | |
1068 first_addr_list_.end()); | |
1069 } | |
1070 needs_sort = (has_ipv6_addresses && addr_list.size() > 1); | |
1071 } | 1092 } |
1072 | 1093 |
1073 if (addr_list.empty()) { | 1094 if (transaction->GetType() == dns_protocol::kTypeA) { |
1074 // TODO(szym): Don't fallback to ProcTask in this case. | 1095 DCHECK_EQ(transaction_a_.get(), transaction); |
1075 OnFailure(ERR_NAME_NOT_RESOLVED, DnsResponse::DNS_PARSE_OK); | 1096 // Place IPv4 addresses after IPv6. |
szym
2013/08/22 15:50:07
Oh oh... Looks like we missed handling of this cas
| |
1097 addr_list_.insert(addr_list_.end(), addr_list.begin(), addr_list.end()); | |
1098 } else { | |
1099 DCHECK_EQ(transaction_aaaa_.get(), transaction); | |
1100 // Place IPv6 addresses before IPv4. | |
1101 addr_list_.insert(addr_list_.begin(), addr_list.begin(), addr_list.end()); | |
1102 } | |
1103 | |
1104 if (needs_two_transactions() && num_completed_transactions_ == 1) { | |
1105 // No need to repeat the suffix search. | |
1106 key_.hostname = transaction->GetHostname(); | |
1107 delegate_->OnFirstDnsTransactionComplete(); | |
1076 return; | 1108 return; |
1077 } | 1109 } |
1078 | 1110 |
szym
2013/08/22 15:50:07
if (addr_list.empty()) {
OnFailure(ERR_NAME_NOT_
| |
1079 if (needs_sort) { | 1111 // If there are multiple addresses, and at least one is IPv6, need to sort |
1080 // Sort could complete synchronously. | 1112 // them. Note that IPv6 addresses are always put before IPv4 ones, so it's |
1113 // sufficient to just check the family of the first address. | |
1114 if (addr_list_.size() > 1 && | |
1115 addr_list_[0].GetFamily() == ADDRESS_FAMILY_IPV6) { | |
1116 // Sort addresses if needed. Sort could complete synchronously. | |
1081 client_->GetAddressSorter()->Sort( | 1117 client_->GetAddressSorter()->Sort( |
1082 addr_list, | 1118 addr_list_, |
1083 base::Bind(&DnsTask::OnSortComplete, | 1119 base::Bind(&DnsTask::OnSortComplete, |
1084 AsWeakPtr(), | 1120 AsWeakPtr(), |
1085 base::TimeTicks::Now(), | 1121 base::TimeTicks::Now())); |
1086 ttl)); | |
1087 } else { | 1122 } else { |
1088 OnSuccess(addr_list, ttl); | 1123 OnSuccess(addr_list_); |
1089 } | 1124 } |
1090 } | 1125 } |
1091 | 1126 |
1092 void OnSortComplete(base::TimeTicks start_time, | 1127 void OnSortComplete(base::TimeTicks start_time, |
1093 base::TimeDelta ttl, | |
1094 bool success, | 1128 bool success, |
1095 const AddressList& addr_list) { | 1129 const AddressList& addr_list) { |
1096 if (!success) { | 1130 if (!success) { |
1097 DNS_HISTOGRAM("AsyncDNS.SortFailure", | 1131 DNS_HISTOGRAM("AsyncDNS.SortFailure", |
1098 base::TimeTicks::Now() - start_time); | 1132 base::TimeTicks::Now() - start_time); |
1099 OnFailure(ERR_DNS_SORT_ERROR, DnsResponse::DNS_PARSE_OK); | 1133 OnFailure(ERR_DNS_SORT_ERROR, DnsResponse::DNS_PARSE_OK); |
1100 return; | 1134 return; |
1101 } | 1135 } |
1102 | 1136 |
1103 DNS_HISTOGRAM("AsyncDNS.SortSuccess", | 1137 DNS_HISTOGRAM("AsyncDNS.SortSuccess", |
1104 base::TimeTicks::Now() - start_time); | 1138 base::TimeTicks::Now() - start_time); |
1105 | 1139 |
1106 // AddressSorter prunes unusable destinations. | 1140 // AddressSorter prunes unusable destinations. |
1107 if (addr_list.empty()) { | 1141 if (addr_list.empty()) { |
1108 LOG(WARNING) << "Address list empty after RFC3484 sort"; | 1142 LOG(WARNING) << "Address list empty after RFC3484 sort"; |
1109 OnFailure(ERR_NAME_NOT_RESOLVED, DnsResponse::DNS_PARSE_OK); | 1143 OnFailure(ERR_NAME_NOT_RESOLVED, DnsResponse::DNS_PARSE_OK); |
1110 return; | 1144 return; |
1111 } | 1145 } |
1112 | 1146 |
1113 OnSuccess(addr_list, ttl); | 1147 OnSuccess(addr_list); |
1114 } | 1148 } |
1115 | 1149 |
1116 void OnFailure(int net_error, DnsResponse::Result result) { | 1150 void OnFailure(int net_error, DnsResponse::Result result) { |
1117 DCHECK_NE(OK, net_error); | 1151 DCHECK_NE(OK, net_error); |
1118 net_log_.EndEvent( | 1152 net_log_.EndEvent( |
1119 NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK, | 1153 NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK, |
1120 base::Bind(&NetLogDnsTaskFailedCallback, net_error, result)); | 1154 base::Bind(&NetLogDnsTaskFailedCallback, net_error, result)); |
1121 callback_.Run(net_error, AddressList(), base::TimeDelta()); | 1155 delegate_->OnDnsTaskComplete(task_start_time_, net_error, AddressList(), |
1156 base::TimeDelta()); | |
1122 } | 1157 } |
1123 | 1158 |
1124 void OnSuccess(const AddressList& addr_list, base::TimeDelta ttl) { | 1159 void OnSuccess(const AddressList& addr_list) { |
1125 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK, | 1160 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK, |
1126 addr_list.CreateNetLogCallback()); | 1161 addr_list.CreateNetLogCallback()); |
1127 callback_.Run(OK, addr_list, ttl); | 1162 delegate_->OnDnsTaskComplete(task_start_time_, OK, addr_list, ttl_); |
1128 } | 1163 } |
1129 | 1164 |
1130 DnsClient* client_; | 1165 DnsClient* client_; |
1131 AddressFamily family_; | 1166 Key key_; |
1167 | |
1132 // The listener to the results of this DnsTask. | 1168 // The listener to the results of this DnsTask. |
1133 Callback callback_; | 1169 Delegate* delegate_; |
1134 const BoundNetLog net_log_; | 1170 const BoundNetLog net_log_; |
1135 | 1171 |
1136 scoped_ptr<DnsTransaction> transaction_; | 1172 scoped_ptr<DnsTransaction> transaction_a_; |
1173 scoped_ptr<DnsTransaction> transaction_aaaa_; | |
1137 | 1174 |
1138 // Results from the first transaction. Used only if |family_| is unspecified. | 1175 unsigned num_completed_transactions_; |
1139 AddressList first_addr_list_; | 1176 |
1140 base::TimeDelta first_ttl_; | 1177 // These are updated as each transaction completes. |
1178 base::TimeDelta ttl_; | |
1179 // IPv6 addresses must appear first in the list. | |
1180 AddressList addr_list_; | |
1181 | |
1182 base::TimeTicks task_start_time_; | |
1141 | 1183 |
1142 DISALLOW_COPY_AND_ASSIGN(DnsTask); | 1184 DISALLOW_COPY_AND_ASSIGN(DnsTask); |
1143 }; | 1185 }; |
1144 | 1186 |
1145 //----------------------------------------------------------------------------- | 1187 //----------------------------------------------------------------------------- |
1146 | 1188 |
1147 // Aggregates all Requests for the same Key. Dispatched via PriorityDispatch. | 1189 // Aggregates all Requests for the same Key. Dispatched via PriorityDispatch. |
1148 class HostResolverImpl::Job : public PrioritizedDispatcher::Job { | 1190 class HostResolverImpl::Job : public PrioritizedDispatcher::Job, |
1191 public HostResolverImpl::DnsTask::Delegate { | |
1149 public: | 1192 public: |
1150 // Creates new job for |key| where |request_net_log| is bound to the | 1193 // Creates new job for |key| where |request_net_log| is bound to the |
1151 // request that spawned it. | 1194 // request that spawned it. |
1152 Job(const base::WeakPtr<HostResolverImpl>& resolver, | 1195 Job(const base::WeakPtr<HostResolverImpl>& resolver, |
1153 const Key& key, | 1196 const Key& key, |
1154 RequestPriority priority, | 1197 RequestPriority priority, |
1155 const BoundNetLog& request_net_log) | 1198 const BoundNetLog& request_net_log) |
1156 : resolver_(resolver), | 1199 : resolver_(resolver), |
1157 key_(key), | 1200 key_(key), |
1158 priority_tracker_(priority), | 1201 priority_tracker_(priority), |
1159 had_non_speculative_request_(false), | 1202 had_non_speculative_request_(false), |
1160 had_dns_config_(false), | 1203 had_dns_config_(false), |
1204 num_occupied_job_slots_(0), | |
1161 dns_task_error_(OK), | 1205 dns_task_error_(OK), |
1162 creation_time_(base::TimeTicks::Now()), | 1206 creation_time_(base::TimeTicks::Now()), |
1163 priority_change_time_(creation_time_), | 1207 priority_change_time_(creation_time_), |
1164 net_log_(BoundNetLog::Make(request_net_log.net_log(), | 1208 net_log_(BoundNetLog::Make(request_net_log.net_log(), |
1165 NetLog::SOURCE_HOST_RESOLVER_IMPL_JOB)) { | 1209 NetLog::SOURCE_HOST_RESOLVER_IMPL_JOB)) { |
1166 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CREATE_JOB); | 1210 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CREATE_JOB); |
1167 | 1211 |
1168 net_log_.BeginEvent( | 1212 net_log_.BeginEvent( |
1169 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, | 1213 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, |
1170 base::Bind(&NetLogJobCreationCallback, | 1214 base::Bind(&NetLogJobCreationCallback, |
1171 request_net_log.source(), | 1215 request_net_log.source(), |
1172 &key_.hostname)); | 1216 &key_.hostname)); |
1173 } | 1217 } |
1174 | 1218 |
1175 virtual ~Job() { | 1219 virtual ~Job() { |
1176 if (is_running()) { | 1220 if (is_running()) { |
1177 // |resolver_| was destroyed with this Job still in flight. | 1221 // |resolver_| was destroyed with this Job still in flight. |
1178 // Clean-up, record in the log, but don't run any callbacks. | 1222 // Clean-up, record in the log, but don't run any callbacks. |
1179 if (is_proc_running()) { | 1223 if (is_proc_running()) { |
1180 proc_task_->Cancel(); | 1224 proc_task_->Cancel(); |
1181 proc_task_ = NULL; | 1225 proc_task_ = NULL; |
1182 } | 1226 } |
1183 // Clean up now for nice NetLog. | 1227 // Clean up now for nice NetLog. |
1184 dns_task_.reset(NULL); | 1228 KillDnsTask(); |
1185 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, | 1229 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, |
1186 ERR_ABORTED); | 1230 ERR_ABORTED); |
1187 } else if (is_queued()) { | 1231 } else if (is_queued()) { |
1188 // |resolver_| was destroyed without running this Job. | 1232 // |resolver_| was destroyed without running this Job. |
1189 // TODO(szym): is there any benefit in having this distinction? | 1233 // TODO(szym): is there any benefit in having this distinction? |
1190 net_log_.AddEvent(NetLog::TYPE_CANCELLED); | 1234 net_log_.AddEvent(NetLog::TYPE_CANCELLED); |
1191 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB); | 1235 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB); |
1192 } | 1236 } |
1193 // else CompleteRequests logged EndEvent. | 1237 // else CompleteRequests logged EndEvent. |
1194 | 1238 |
1195 // Log any remaining Requests as cancelled. | 1239 // Log any remaining Requests as cancelled. |
1196 for (RequestsList::const_iterator it = requests_.begin(); | 1240 for (RequestsList::const_iterator it = requests_.begin(); |
1197 it != requests_.end(); ++it) { | 1241 it != requests_.end(); ++it) { |
1198 Request* req = *it; | 1242 Request* req = *it; |
1199 if (req->was_canceled()) | 1243 if (req->was_canceled()) |
1200 continue; | 1244 continue; |
1201 DCHECK_EQ(this, req->job()); | 1245 DCHECK_EQ(this, req->job()); |
1202 LogCancelRequest(req->source_net_log(), req->request_net_log(), | 1246 LogCancelRequest(req->source_net_log(), req->request_net_log(), |
1203 req->info()); | 1247 req->info()); |
1204 } | 1248 } |
1205 } | 1249 } |
1206 | 1250 |
1207 // Add this job to the dispatcher. | 1251 // Add this job to the dispatcher. If "at_head" is true, adds at the front |
1208 void Schedule() { | 1252 // of the queue. |
1209 handle_ = resolver_->dispatcher_.Add(this, priority()); | 1253 void Schedule(bool at_head) { |
1254 DCHECK(!is_queued()); | |
1255 PrioritizedDispatcher::Handle handle; | |
1256 if (!at_head) { | |
1257 handle = resolver_->dispatcher_.Add(this, priority()); | |
1258 } else { | |
1259 handle = resolver_->dispatcher_.AddAtHead(this, priority()); | |
1260 } | |
1261 // The dispatcher could have started |this| in the above call to Add, which | |
1262 // could have called Schedule again. In that case |handle| will be null, | |
1263 // but |handle_| may have been set by the other nested call to Schedule. | |
1264 if (!handle.is_null()) { | |
1265 DCHECK(handle_.is_null()); | |
1266 handle_ = handle; | |
1267 } | |
1210 } | 1268 } |
1211 | 1269 |
1212 void AddRequest(scoped_ptr<Request> req) { | 1270 void AddRequest(scoped_ptr<Request> req) { |
1213 DCHECK_EQ(key_.hostname, req->info().hostname()); | 1271 DCHECK_EQ(key_.hostname, req->info().hostname()); |
1214 | 1272 |
1215 req->set_job(this); | 1273 req->set_job(this); |
1216 priority_tracker_.Add(req->priority()); | 1274 priority_tracker_.Add(req->priority()); |
1217 | 1275 |
1218 req->request_net_log().AddEvent( | 1276 req->request_net_log().AddEvent( |
1219 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_ATTACH, | 1277 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_ATTACH, |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1267 // Called from AbortAllInProgressJobs. Completes all requests and destroys | 1325 // Called from AbortAllInProgressJobs. Completes all requests and destroys |
1268 // the job. This currently assumes the abort is due to a network change. | 1326 // the job. This currently assumes the abort is due to a network change. |
1269 void Abort() { | 1327 void Abort() { |
1270 DCHECK(is_running()); | 1328 DCHECK(is_running()); |
1271 CompleteRequestsWithError(ERR_NETWORK_CHANGED); | 1329 CompleteRequestsWithError(ERR_NETWORK_CHANGED); |
1272 } | 1330 } |
1273 | 1331 |
1274 // If DnsTask present, abort it and fall back to ProcTask. | 1332 // If DnsTask present, abort it and fall back to ProcTask. |
1275 void AbortDnsTask() { | 1333 void AbortDnsTask() { |
1276 if (dns_task_) { | 1334 if (dns_task_) { |
1277 dns_task_.reset(); | 1335 KillDnsTask(); |
1278 dns_task_error_ = OK; | 1336 dns_task_error_ = OK; |
1279 StartProcTask(); | 1337 StartProcTask(); |
1280 } | 1338 } |
1281 } | 1339 } |
1282 | 1340 |
1283 // Called by HostResolverImpl when this job is evicted due to queue overflow. | 1341 // Called by HostResolverImpl when this job is evicted due to queue overflow. |
1284 // Completes all requests and destroys the job. | 1342 // Completes all requests and destroys the job. |
1285 void OnEvicted() { | 1343 void OnEvicted() { |
1286 DCHECK(!is_running()); | 1344 DCHECK(!is_running()); |
1287 DCHECK(is_queued()); | 1345 DCHECK(is_queued()); |
(...skipping 28 matching lines...) Expand all Loading... | |
1316 | 1374 |
1317 bool is_queued() const { | 1375 bool is_queued() const { |
1318 return !handle_.is_null(); | 1376 return !handle_.is_null(); |
1319 } | 1377 } |
1320 | 1378 |
1321 bool is_running() const { | 1379 bool is_running() const { |
1322 return is_dns_running() || is_proc_running(); | 1380 return is_dns_running() || is_proc_running(); |
1323 } | 1381 } |
1324 | 1382 |
1325 private: | 1383 private: |
1384 void KillDnsTask() { | |
1385 if (dns_task_) { | |
1386 ReduceToOneJobSlot(); | |
1387 dns_task_.reset(); | |
1388 } | |
1389 } | |
1390 | |
1391 // Reduce the number of job slots occupied and queued in the dispatcher | |
1392 // to one. If the second Job slot is queued in the dispatcher, cancels the | |
1393 // queued job. Otherwise, the second Job has been started by the | |
1394 // PrioritizedDispatcher, so signals it is complete. | |
1395 void ReduceToOneJobSlot() { | |
1396 DCHECK_GE(num_occupied_job_slots_, 1u); | |
1397 if (is_queued()) { | |
1398 resolver_->dispatcher_.Cancel(handle_); | |
1399 handle_.Reset(); | |
1400 } else if (num_occupied_job_slots_ > 1) { | |
1401 resolver_->dispatcher_.OnJobFinished(); | |
1402 --num_occupied_job_slots_; | |
1403 } | |
1404 DCHECK_EQ(1u, num_occupied_job_slots_); | |
1405 } | |
1406 | |
1326 void UpdatePriority() { | 1407 void UpdatePriority() { |
1327 if (is_queued()) { | 1408 if (is_queued()) { |
1328 if (priority() != static_cast<RequestPriority>(handle_.priority())) | 1409 if (priority() != static_cast<RequestPriority>(handle_.priority())) |
1329 priority_change_time_ = base::TimeTicks::Now(); | 1410 priority_change_time_ = base::TimeTicks::Now(); |
1330 handle_ = resolver_->dispatcher_.ChangePriority(handle_, priority()); | 1411 handle_ = resolver_->dispatcher_.ChangePriority(handle_, priority()); |
1331 } | 1412 } |
1332 } | 1413 } |
1333 | 1414 |
1334 AddressList MakeAddressListForRequest(const AddressList& list) const { | 1415 AddressList MakeAddressListForRequest(const AddressList& list) const { |
1335 if (requests_.empty()) | 1416 if (requests_.empty()) |
1336 return list; | 1417 return list; |
1337 return AddressList::CopyWithPort(list, requests_.front()->info().port()); | 1418 return AddressList::CopyWithPort(list, requests_.front()->info().port()); |
1338 } | 1419 } |
1339 | 1420 |
1340 // PriorityDispatch::Job: | 1421 // PriorityDispatch::Job: |
1341 virtual void Start() OVERRIDE { | 1422 virtual void Start() OVERRIDE { |
1423 DCHECK_LE(num_occupied_job_slots_, 1u); | |
1424 | |
1425 handle_.Reset(); | |
1426 ++num_occupied_job_slots_; | |
1427 | |
1428 if (num_occupied_job_slots_ == 2) { | |
1429 StartSecondDnsTransaction(); | |
1430 return; | |
1431 } | |
1432 | |
1342 DCHECK(!is_running()); | 1433 DCHECK(!is_running()); |
1343 handle_.Reset(); | |
1344 | 1434 |
1345 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_STARTED); | 1435 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_STARTED); |
1346 | 1436 |
1347 had_dns_config_ = resolver_->HaveDnsConfig(); | 1437 had_dns_config_ = resolver_->HaveDnsConfig(); |
1348 | 1438 |
1349 base::TimeTicks now = base::TimeTicks::Now(); | 1439 base::TimeTicks now = base::TimeTicks::Now(); |
1350 base::TimeDelta queue_time = now - creation_time_; | 1440 base::TimeDelta queue_time = now - creation_time_; |
1351 base::TimeDelta queue_time_after_change = now - priority_change_time_; | 1441 base::TimeDelta queue_time_after_change = now - priority_change_time_; |
1352 | 1442 |
1353 if (had_dns_config_) { | 1443 if (had_dns_config_) { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1437 ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds); | 1527 ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds); |
1438 | 1528 |
1439 // Don't store the |ttl| in cache since it's not obtained from the server. | 1529 // Don't store the |ttl| in cache since it's not obtained from the server. |
1440 CompleteRequests( | 1530 CompleteRequests( |
1441 HostCache::Entry(net_error, MakeAddressListForRequest(addr_list)), | 1531 HostCache::Entry(net_error, MakeAddressListForRequest(addr_list)), |
1442 ttl); | 1532 ttl); |
1443 } | 1533 } |
1444 | 1534 |
1445 void StartDnsTask() { | 1535 void StartDnsTask() { |
1446 DCHECK(resolver_->HaveDnsConfig()); | 1536 DCHECK(resolver_->HaveDnsConfig()); |
1447 base::TimeTicks start_time = base::TimeTicks::Now(); | 1537 dns_task_.reset(new DnsTask(resolver_->dns_client_.get(), key_, this, |
1448 dns_task_.reset(new DnsTask( | 1538 net_log_)); |
1449 resolver_->dns_client_.get(), | |
1450 key_, | |
1451 base::Bind(&Job::OnDnsTaskComplete, base::Unretained(this), start_time), | |
1452 net_log_)); | |
1453 | 1539 |
1454 dns_task_->Start(); | 1540 dns_task_->StartFirstTransaction(); |
1541 // Schedule a second transaction, if needed. | |
1542 if (dns_task_->needs_two_transactions()) | |
1543 Schedule(true); | |
1544 } | |
1545 | |
1546 void StartSecondDnsTransaction() { | |
1547 DCHECK(dns_task_->needs_two_transactions()); | |
1548 dns_task_->StartSecondTransaction(); | |
1455 } | 1549 } |
1456 | 1550 |
1457 // Called if DnsTask fails. It is posted from StartDnsTask, so Job may be | 1551 // Called if DnsTask fails. It is posted from StartDnsTask, so Job may be |
1458 // deleted before this callback. In this case dns_task is deleted as well, | 1552 // deleted before this callback. In this case dns_task is deleted as well, |
1459 // so we use it as indicator whether Job is still valid. | 1553 // so we use it as indicator whether Job is still valid. |
1460 void OnDnsTaskFailure(const base::WeakPtr<DnsTask>& dns_task, | 1554 void OnDnsTaskFailure(const base::WeakPtr<DnsTask>& dns_task, |
1461 base::TimeDelta duration, | 1555 base::TimeDelta duration, |
1462 int net_error) { | 1556 int net_error) { |
1463 DNS_HISTOGRAM("AsyncDNS.ResolveFail", duration); | 1557 DNS_HISTOGRAM("AsyncDNS.ResolveFail", duration); |
1464 | 1558 |
1465 if (dns_task == NULL) | 1559 if (dns_task == NULL) |
1466 return; | 1560 return; |
1467 | 1561 |
1468 dns_task_error_ = net_error; | 1562 dns_task_error_ = net_error; |
1469 | 1563 |
1470 // TODO(szym): Run ServeFromHosts now if nsswitch.conf says so. | 1564 // TODO(szym): Run ServeFromHosts now if nsswitch.conf says so. |
1471 // http://crbug.com/117655 | 1565 // http://crbug.com/117655 |
1472 | 1566 |
1473 // TODO(szym): Some net errors indicate lack of connectivity. Starting | 1567 // TODO(szym): Some net errors indicate lack of connectivity. Starting |
1474 // ProcTask in that case is a waste of time. | 1568 // ProcTask in that case is a waste of time. |
1475 if (resolver_->fallback_to_proctask_) { | 1569 if (resolver_->fallback_to_proctask_) { |
1476 dns_task_.reset(); | 1570 KillDnsTask(); |
1477 StartProcTask(); | 1571 StartProcTask(); |
1478 } else { | 1572 } else { |
1479 UmaAsyncDnsResolveStatus(RESOLVE_STATUS_FAIL); | 1573 UmaAsyncDnsResolveStatus(RESOLVE_STATUS_FAIL); |
1480 CompleteRequestsWithError(net_error); | 1574 CompleteRequestsWithError(net_error); |
1481 } | 1575 } |
1482 } | 1576 } |
1483 | 1577 |
1484 // Called by DnsTask when it completes. | 1578 |
1485 void OnDnsTaskComplete(base::TimeTicks start_time, | 1579 // HostResolverImpl::DnsTask::Delegate implementation: |
1486 int net_error, | 1580 |
1487 const AddressList& addr_list, | 1581 virtual void OnDnsTaskComplete(base::TimeTicks start_time, |
1488 base::TimeDelta ttl) { | 1582 int net_error, |
1583 const AddressList& addr_list, | |
1584 base::TimeDelta ttl) OVERRIDE { | |
1489 DCHECK(is_dns_running()); | 1585 DCHECK(is_dns_running()); |
1490 | 1586 |
1491 base::TimeDelta duration = base::TimeTicks::Now() - start_time; | 1587 base::TimeDelta duration = base::TimeTicks::Now() - start_time; |
1492 if (net_error != OK) { | 1588 if (net_error != OK) { |
1493 OnDnsTaskFailure(dns_task_->AsWeakPtr(), duration, net_error); | 1589 OnDnsTaskFailure(dns_task_->AsWeakPtr(), duration, net_error); |
1494 return; | 1590 return; |
1495 } | 1591 } |
1496 DNS_HISTOGRAM("AsyncDNS.ResolveSuccess", duration); | 1592 DNS_HISTOGRAM("AsyncDNS.ResolveSuccess", duration); |
1497 // Log DNS lookups based on |address_family|. | 1593 // Log DNS lookups based on |address_family|. |
1498 switch(key_.address_family) { | 1594 switch(key_.address_family) { |
(...skipping 14 matching lines...) Expand all Loading... | |
1513 resolver_->OnDnsTaskResolve(OK); | 1609 resolver_->OnDnsTaskResolve(OK); |
1514 | 1610 |
1515 base::TimeDelta bounded_ttl = | 1611 base::TimeDelta bounded_ttl = |
1516 std::max(ttl, base::TimeDelta::FromSeconds(kMinimumTTLSeconds)); | 1612 std::max(ttl, base::TimeDelta::FromSeconds(kMinimumTTLSeconds)); |
1517 | 1613 |
1518 CompleteRequests( | 1614 CompleteRequests( |
1519 HostCache::Entry(net_error, MakeAddressListForRequest(addr_list), ttl), | 1615 HostCache::Entry(net_error, MakeAddressListForRequest(addr_list), ttl), |
1520 bounded_ttl); | 1616 bounded_ttl); |
1521 } | 1617 } |
1522 | 1618 |
1619 virtual void OnFirstDnsTransactionComplete() OVERRIDE { | |
1620 DCHECK(dns_task_->needs_two_transactions()); | |
1621 DCHECK_EQ(dns_task_->needs_another_transaction(), is_queued()); | |
1622 // No longer need to occupy two dispatcher slots. | |
1623 ReduceToOneJobSlot(); | |
1624 | |
1625 // We already have a job slot at the dispatcher, so if the second | |
1626 // transaction hasn't started, reuse it now instead of waiting in the queue | |
1627 // for the second slot. | |
1628 if (dns_task_->needs_another_transaction()) | |
1629 dns_task_->StartSecondTransaction(); | |
1630 } | |
1631 | |
1523 // Performs Job's last rites. Completes all Requests. Deletes this. | 1632 // Performs Job's last rites. Completes all Requests. Deletes this. |
1524 void CompleteRequests(const HostCache::Entry& entry, | 1633 void CompleteRequests(const HostCache::Entry& entry, |
1525 base::TimeDelta ttl) { | 1634 base::TimeDelta ttl) { |
1526 CHECK(resolver_.get()); | 1635 CHECK(resolver_.get()); |
1527 | 1636 |
1528 // This job must be removed from resolver's |jobs_| now to make room for a | 1637 // This job must be removed from resolver's |jobs_| now to make room for a |
1529 // new job with the same key in case one of the OnComplete callbacks decides | 1638 // new job with the same key in case one of the OnComplete callbacks decides |
1530 // to spawn one. Consequently, the job deletes itself when CompleteRequests | 1639 // to spawn one. Consequently, the job deletes itself when CompleteRequests |
1531 // is done. | 1640 // is done. |
1532 scoped_ptr<Job> self_deleter(this); | 1641 scoped_ptr<Job> self_deleter(this); |
1533 | 1642 |
1534 resolver_->RemoveJob(this); | 1643 resolver_->RemoveJob(this); |
1535 | 1644 |
1536 if (is_running()) { | 1645 if (is_running()) { |
1537 DCHECK(!is_queued()); | |
1538 if (is_proc_running()) { | 1646 if (is_proc_running()) { |
1647 DCHECK(!is_queued()); | |
1539 proc_task_->Cancel(); | 1648 proc_task_->Cancel(); |
1540 proc_task_ = NULL; | 1649 proc_task_ = NULL; |
1541 } | 1650 } |
1542 dns_task_.reset(); | 1651 KillDnsTask(); |
1543 | 1652 |
1544 // Signal dispatcher that a slot has opened. | 1653 // Signal dispatcher that a slot has opened. |
1545 resolver_->dispatcher_.OnJobFinished(); | 1654 resolver_->dispatcher_.OnJobFinished(); |
1546 } else if (is_queued()) { | 1655 } else if (is_queued()) { |
1547 resolver_->dispatcher_.Cancel(handle_); | 1656 resolver_->dispatcher_.Cancel(handle_); |
1548 handle_.Reset(); | 1657 handle_.Reset(); |
1549 } | 1658 } |
1550 | 1659 |
1551 if (num_active_requests() == 0) { | 1660 if (num_active_requests() == 0) { |
1552 net_log_.AddEvent(NetLog::TYPE_CANCELLED); | 1661 net_log_.AddEvent(NetLog::TYPE_CANCELLED); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1626 Key key_; | 1735 Key key_; |
1627 | 1736 |
1628 // Tracks the highest priority across |requests_|. | 1737 // Tracks the highest priority across |requests_|. |
1629 PriorityTracker priority_tracker_; | 1738 PriorityTracker priority_tracker_; |
1630 | 1739 |
1631 bool had_non_speculative_request_; | 1740 bool had_non_speculative_request_; |
1632 | 1741 |
1633 // Distinguishes measurements taken while DnsClient was fully configured. | 1742 // Distinguishes measurements taken while DnsClient was fully configured. |
1634 bool had_dns_config_; | 1743 bool had_dns_config_; |
1635 | 1744 |
1745 // Number of slots occupied by this Job in resolver's PrioritizedDispatcher. | |
1746 unsigned num_occupied_job_slots_; | |
1747 | |
1636 // Result of DnsTask. | 1748 // Result of DnsTask. |
1637 int dns_task_error_; | 1749 int dns_task_error_; |
1638 | 1750 |
1639 const base::TimeTicks creation_time_; | 1751 const base::TimeTicks creation_time_; |
1640 base::TimeTicks priority_change_time_; | 1752 base::TimeTicks priority_change_time_; |
1641 | 1753 |
1642 BoundNetLog net_log_; | 1754 BoundNetLog net_log_; |
1643 | 1755 |
1644 // Resolves the host using a HostResolverProc. | 1756 // Resolves the host using a HostResolverProc. |
1645 scoped_refptr<ProcTask> proc_task_; | 1757 scoped_refptr<ProcTask> proc_task_; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1713 { | 1825 { |
1714 DnsConfig dns_config; | 1826 DnsConfig dns_config; |
1715 NetworkChangeNotifier::GetDnsConfig(&dns_config); | 1827 NetworkChangeNotifier::GetDnsConfig(&dns_config); |
1716 received_dns_config_ = dns_config.IsValid(); | 1828 received_dns_config_ = dns_config.IsValid(); |
1717 } | 1829 } |
1718 | 1830 |
1719 fallback_to_proctask_ = !ConfigureAsyncDnsNoFallbackFieldTrial(); | 1831 fallback_to_proctask_ = !ConfigureAsyncDnsNoFallbackFieldTrial(); |
1720 } | 1832 } |
1721 | 1833 |
1722 HostResolverImpl::~HostResolverImpl() { | 1834 HostResolverImpl::~HostResolverImpl() { |
1723 // This will also cancel all outstanding requests. | 1835 // Prevent the dispatcher from starting new jobs. |
1836 dispatcher_.Disable(); | |
1837 // It's now safe for Jobs to call KillDsnTask on destruction, because | |
1838 // OnJobComplete will not start any new jobs. | |
1724 STLDeleteValues(&jobs_); | 1839 STLDeleteValues(&jobs_); |
1725 | 1840 |
1726 NetworkChangeNotifier::RemoveIPAddressObserver(this); | 1841 NetworkChangeNotifier::RemoveIPAddressObserver(this); |
1727 NetworkChangeNotifier::RemoveDNSObserver(this); | 1842 NetworkChangeNotifier::RemoveDNSObserver(this); |
1728 } | 1843 } |
1729 | 1844 |
1730 void HostResolverImpl::SetMaxQueuedJobs(size_t value) { | 1845 void HostResolverImpl::SetMaxQueuedJobs(size_t value) { |
1731 DCHECK_EQ(0u, dispatcher_.num_queued_jobs()); | 1846 DCHECK_EQ(0u, dispatcher_.num_queued_jobs()); |
1732 DCHECK_GT(value, 0u); | 1847 DCHECK_GT(value, 0u); |
1733 max_queued_jobs_ = value; | 1848 max_queued_jobs_ = value; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1766 } | 1881 } |
1767 | 1882 |
1768 // Next we need to attach our request to a "job". This job is responsible for | 1883 // Next we need to attach our request to a "job". This job is responsible for |
1769 // calling "getaddrinfo(hostname)" on a worker thread. | 1884 // calling "getaddrinfo(hostname)" on a worker thread. |
1770 | 1885 |
1771 JobMap::iterator jobit = jobs_.find(key); | 1886 JobMap::iterator jobit = jobs_.find(key); |
1772 Job* job; | 1887 Job* job; |
1773 if (jobit == jobs_.end()) { | 1888 if (jobit == jobs_.end()) { |
1774 job = | 1889 job = |
1775 new Job(weak_ptr_factory_.GetWeakPtr(), key, priority, request_net_log); | 1890 new Job(weak_ptr_factory_.GetWeakPtr(), key, priority, request_net_log); |
1776 job->Schedule(); | 1891 job->Schedule(false); |
1777 | 1892 |
1778 // Check for queue overflow. | 1893 // Check for queue overflow. |
1779 if (dispatcher_.num_queued_jobs() > max_queued_jobs_) { | 1894 if (dispatcher_.num_queued_jobs() > max_queued_jobs_) { |
1780 Job* evicted = static_cast<Job*>(dispatcher_.EvictOldestLowest()); | 1895 Job* evicted = static_cast<Job*>(dispatcher_.EvictOldestLowest()); |
1781 DCHECK(evicted); | 1896 DCHECK(evicted); |
1782 evicted->OnEvicted(); // Deletes |evicted|. | 1897 evicted->OnEvicted(); // Deletes |evicted|. |
1783 if (evicted == job) { | 1898 if (evicted == job) { |
1784 rv = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE; | 1899 rv = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE; |
1785 LogFinishRequest(source_net_log, request_net_log, info, rv); | 1900 LogFinishRequest(source_net_log, request_net_log, info, rv); |
1786 return rv; | 1901 return rv; |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2063 Job* job = it->second; | 2178 Job* job = it->second; |
2064 if (job->is_running()) { | 2179 if (job->is_running()) { |
2065 jobs_to_abort.push_back(job); | 2180 jobs_to_abort.push_back(job); |
2066 jobs_.erase(it++); | 2181 jobs_.erase(it++); |
2067 } else { | 2182 } else { |
2068 DCHECK(job->is_queued()); | 2183 DCHECK(job->is_queued()); |
2069 ++it; | 2184 ++it; |
2070 } | 2185 } |
2071 } | 2186 } |
2072 | 2187 |
2073 // Check if no dispatcher slots leaked out. | |
2074 DCHECK_EQ(dispatcher_.num_running_jobs(), jobs_to_abort.size()); | |
2075 | |
2076 // Life check to bail once |this| is deleted. | 2188 // Life check to bail once |this| is deleted. |
2077 base::WeakPtr<HostResolverImpl> self = weak_ptr_factory_.GetWeakPtr(); | 2189 base::WeakPtr<HostResolverImpl> self = weak_ptr_factory_.GetWeakPtr(); |
2078 | 2190 |
2079 // Then Abort them. | 2191 // Then Abort them. |
2080 for (size_t i = 0; self.get() && i < jobs_to_abort.size(); ++i) { | 2192 for (size_t i = 0; self.get() && i < jobs_to_abort.size(); ++i) { |
2081 jobs_to_abort[i]->Abort(); | 2193 jobs_to_abort[i]->Abort(); |
2082 jobs_to_abort[i] = NULL; | 2194 jobs_to_abort[i] = NULL; |
2083 } | 2195 } |
2084 } | 2196 } |
2085 | 2197 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2197 } | 2309 } |
2198 DnsConfig dns_config; | 2310 DnsConfig dns_config; |
2199 NetworkChangeNotifier::GetDnsConfig(&dns_config); | 2311 NetworkChangeNotifier::GetDnsConfig(&dns_config); |
2200 dns_client_->SetConfig(dns_config); | 2312 dns_client_->SetConfig(dns_config); |
2201 num_dns_failures_ = 0; | 2313 num_dns_failures_ = 0; |
2202 if (dns_config.IsValid()) | 2314 if (dns_config.IsValid()) |
2203 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); | 2315 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); |
2204 } | 2316 } |
2205 | 2317 |
2206 } // namespace net | 2318 } // namespace net |
OLD | NEW |