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