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 |