| 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/dns_config_service.h" | 5 #include "net/dns/dns_config_service.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/values.h" | 8 #include "base/values.h" |
| 9 #include "net/base/ip_endpoint.h" | 9 #include "net/base/ip_endpoint.h" |
| 10 | 10 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 dict->SetBoolean("edns0", edns0); | 68 dict->SetBoolean("edns0", edns0); |
| 69 dict->SetInteger("num_hosts", hosts.size()); | 69 dict->SetInteger("num_hosts", hosts.size()); |
| 70 | 70 |
| 71 return dict; | 71 return dict; |
| 72 } | 72 } |
| 73 | 73 |
| 74 | 74 |
| 75 DnsConfigService::DnsConfigService() | 75 DnsConfigService::DnsConfigService() |
| 76 : have_config_(false), | 76 : have_config_(false), |
| 77 have_hosts_(false), | 77 have_hosts_(false), |
| 78 need_update_(false) {} | 78 need_update_(false), |
| 79 last_sent_empty_(true) {} |
| 79 | 80 |
| 80 DnsConfigService::~DnsConfigService() { | 81 DnsConfigService::~DnsConfigService() { |
| 81 // Must always clean up. | 82 // Must always clean up. |
| 82 NetworkChangeNotifier::RemoveDNSObserver(this); | 83 NetworkChangeNotifier::RemoveDNSObserver(this); |
| 83 } | 84 } |
| 84 | 85 |
| 85 void DnsConfigService::Read(const CallbackType& callback) { | 86 void DnsConfigService::Read(const CallbackType& callback) { |
| 86 DCHECK(CalledOnValidThread()); | 87 DCHECK(CalledOnValidThread()); |
| 87 DCHECK(!callback.is_null()); | 88 DCHECK(!callback.is_null()); |
| 88 DCHECK(callback_.is_null()); | 89 DCHECK(callback_.is_null()); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 need_update_ = true; | 140 need_update_ = true; |
| 140 } | 141 } |
| 141 | 142 |
| 142 have_hosts_ = true; | 143 have_hosts_ = true; |
| 143 if (have_config_) | 144 if (have_config_) |
| 144 OnCompleteConfig(); | 145 OnCompleteConfig(); |
| 145 } | 146 } |
| 146 | 147 |
| 147 void DnsConfigService::StartTimer() { | 148 void DnsConfigService::StartTimer() { |
| 148 DCHECK(CalledOnValidThread()); | 149 DCHECK(CalledOnValidThread()); |
| 150 if (last_sent_empty_) { |
| 151 DCHECK(!timer_.IsRunning()); |
| 152 return; // No need to withdraw again. |
| 153 } |
| 149 timer_.Stop(); | 154 timer_.Stop(); |
| 150 | 155 |
| 151 // Give it a short timeout to come up with a valid config. Otherwise withdraw | 156 // Give it a short timeout to come up with a valid config. Otherwise withdraw |
| 152 // the config from the receiver. The goal is to avoid perceivable network | 157 // the config from the receiver. The goal is to avoid perceivable network |
| 153 // outage (when using the wrong config) but at the same time avoid | 158 // outage (when using the wrong config) but at the same time avoid |
| 154 // unnecessary Job aborts in HostResolverImpl. The signals come from multiple | 159 // unnecessary Job aborts in HostResolverImpl. The signals come from multiple |
| 155 // sources so it might receive multiple events during a config change. | 160 // sources so it might receive multiple events during a config change. |
| 156 | 161 |
| 157 // DHCP and user-induced changes are on the order of seconds, so 100ms should | 162 // DHCP and user-induced changes are on the order of seconds, so 100ms should |
| 158 // not add perceivable delay. On the other hand, config readers should finish | 163 // not add perceivable delay. On the other hand, config readers should finish |
| 159 // within 100ms with the rare exception of I/O block or extra large HOSTS. | 164 // within 100ms with the rare exception of I/O block or extra large HOSTS. |
| 160 const base::TimeDelta kTimeout = base::TimeDelta::FromMilliseconds(100); | 165 const base::TimeDelta kTimeout = base::TimeDelta::FromMilliseconds(100); |
| 161 | 166 |
| 162 timer_.Start(FROM_HERE, | 167 timer_.Start(FROM_HERE, |
| 163 kTimeout, | 168 kTimeout, |
| 164 this, | 169 this, |
| 165 &DnsConfigService::OnTimeout); | 170 &DnsConfigService::OnTimeout); |
| 166 } | 171 } |
| 167 | 172 |
| 168 void DnsConfigService::OnTimeout() { | 173 void DnsConfigService::OnTimeout() { |
| 169 DCHECK(CalledOnValidThread()); | 174 DCHECK(CalledOnValidThread()); |
| 175 DCHECK(!last_sent_empty_); |
| 170 // Indicate that even if there is no change in On*Read, we will need to | 176 // Indicate that even if there is no change in On*Read, we will need to |
| 171 // update the receiver when the config becomes complete. | 177 // update the receiver when the config becomes complete. |
| 172 need_update_ = true; | 178 need_update_ = true; |
| 173 // Empty config is considered invalid. | 179 // Empty config is considered invalid. |
| 180 last_sent_empty_ = true; |
| 174 callback_.Run(DnsConfig()); | 181 callback_.Run(DnsConfig()); |
| 175 } | 182 } |
| 176 | 183 |
| 177 void DnsConfigService::OnCompleteConfig() { | 184 void DnsConfigService::OnCompleteConfig() { |
| 178 timer_.Stop(); | 185 timer_.Stop(); |
| 179 if (need_update_) { | 186 if (!need_update_) |
| 180 need_update_ = false; | 187 return; |
| 181 callback_.Run(dns_config_); | 188 need_update_ = false; |
| 182 } | 189 last_sent_empty_ = false; |
| 190 callback_.Run(dns_config_); |
| 183 } | 191 } |
| 184 | 192 |
| 185 } // namespace net | 193 } // namespace net |
| 186 | 194 |
| OLD | NEW |