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 return; // No need to withdraw again. | |
mmenke
2012/06/11 22:46:25
optional: May also want to DHCECK that the timer
| |
149 timer_.Stop(); | 152 timer_.Stop(); |
150 | 153 |
151 // Give it a short timeout to come up with a valid config. Otherwise withdraw | 154 // 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 | 155 // 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 | 156 // outage (when using the wrong config) but at the same time avoid |
154 // unnecessary Job aborts in HostResolverImpl. The signals come from multiple | 157 // unnecessary Job aborts in HostResolverImpl. The signals come from multiple |
155 // sources so it might receive multiple events during a config change. | 158 // sources so it might receive multiple events during a config change. |
156 | 159 |
157 // DHCP and user-induced changes are on the order of seconds, so 100ms should | 160 // 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 | 161 // 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. | 162 // within 100ms with the rare exception of I/O block or extra large HOSTS. |
160 const base::TimeDelta kTimeout = base::TimeDelta::FromMilliseconds(100); | 163 const base::TimeDelta kTimeout = base::TimeDelta::FromMilliseconds(100); |
161 | 164 |
162 timer_.Start(FROM_HERE, | 165 timer_.Start(FROM_HERE, |
163 kTimeout, | 166 kTimeout, |
164 this, | 167 this, |
165 &DnsConfigService::OnTimeout); | 168 &DnsConfigService::OnTimeout); |
166 } | 169 } |
167 | 170 |
168 void DnsConfigService::OnTimeout() { | 171 void DnsConfigService::OnTimeout() { |
169 DCHECK(CalledOnValidThread()); | 172 DCHECK(CalledOnValidThread()); |
173 DCHECK(!last_sent_empty_); | |
170 // Indicate that even if there is no change in On*Read, we will need to | 174 // Indicate that even if there is no change in On*Read, we will need to |
171 // update the receiver when the config becomes complete. | 175 // update the receiver when the config becomes complete. |
172 need_update_ = true; | 176 need_update_ = true; |
173 // Empty config is considered invalid. | 177 // Empty config is considered invalid. |
178 last_sent_empty_ = true; | |
174 callback_.Run(DnsConfig()); | 179 callback_.Run(DnsConfig()); |
175 } | 180 } |
176 | 181 |
177 void DnsConfigService::OnCompleteConfig() { | 182 void DnsConfigService::OnCompleteConfig() { |
178 timer_.Stop(); | 183 timer_.Stop(); |
179 if (need_update_) { | 184 if (!need_update_) |
180 need_update_ = false; | 185 return; |
181 callback_.Run(dns_config_); | 186 need_update_ = false; |
182 } | 187 last_sent_empty_ = false; |
188 callback_.Run(dns_config_); | |
183 } | 189 } |
184 | 190 |
185 } // namespace net | 191 } // namespace net |
186 | 192 |
OLD | NEW |