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/base/network_change_notifier_win.h" | 5 #include "net/base/network_change_notifier_win.h" |
6 | 6 |
7 #include <iphlpapi.h> | 7 #include <iphlpapi.h> |
8 #include <winsock2.h> | 8 #include <winsock2.h> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 dns_config_service_thread_(new DnsConfigServiceThread()), | 59 dns_config_service_thread_(new DnsConfigServiceThread()), |
60 last_computed_connection_type_(RecomputeCurrentConnectionType()), | 60 last_computed_connection_type_(RecomputeCurrentConnectionType()), |
61 last_announced_offline_(last_computed_connection_type_ == | 61 last_announced_offline_(last_computed_connection_type_ == |
62 CONNECTION_NONE), | 62 CONNECTION_NONE), |
63 weak_factory_(this) { | 63 weak_factory_(this) { |
64 memset(&addr_overlapped_, 0, sizeof addr_overlapped_); | 64 memset(&addr_overlapped_, 0, sizeof addr_overlapped_); |
65 addr_overlapped_.hEvent = WSACreateEvent(); | 65 addr_overlapped_.hEvent = WSACreateEvent(); |
66 } | 66 } |
67 | 67 |
68 NetworkChangeNotifierWin::~NetworkChangeNotifierWin() { | 68 NetworkChangeNotifierWin::~NetworkChangeNotifierWin() { |
| 69 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
69 if (is_watching_) { | 70 if (is_watching_) { |
70 CancelIPChangeNotify(&addr_overlapped_); | 71 CancelIPChangeNotify(&addr_overlapped_); |
71 addr_watcher_.StopWatching(); | 72 addr_watcher_.StopWatching(); |
72 } | 73 } |
73 WSACloseEvent(addr_overlapped_.hEvent); | 74 WSACloseEvent(addr_overlapped_.hEvent); |
74 } | 75 } |
75 | 76 |
76 // static | 77 // static |
77 NetworkChangeNotifier::NetworkChangeCalculatorParams | 78 NetworkChangeNotifier::NetworkChangeCalculatorParams |
78 NetworkChangeNotifierWin::NetworkChangeCalculatorParamsWin() { | 79 NetworkChangeNotifierWin::NetworkChangeCalculatorParamsWin() { |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 return last_computed_connection_type_; | 223 return last_computed_connection_type_; |
223 } | 224 } |
224 | 225 |
225 void NetworkChangeNotifierWin::SetCurrentConnectionType( | 226 void NetworkChangeNotifierWin::SetCurrentConnectionType( |
226 ConnectionType connection_type) { | 227 ConnectionType connection_type) { |
227 base::AutoLock auto_lock(last_computed_connection_type_lock_); | 228 base::AutoLock auto_lock(last_computed_connection_type_lock_); |
228 last_computed_connection_type_ = connection_type; | 229 last_computed_connection_type_ = connection_type; |
229 } | 230 } |
230 | 231 |
231 void NetworkChangeNotifierWin::OnObjectSignaled(HANDLE object) { | 232 void NetworkChangeNotifierWin::OnObjectSignaled(HANDLE object) { |
232 DCHECK(CalledOnValidThread()); | 233 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
233 DCHECK(is_watching_); | 234 DCHECK(is_watching_); |
234 is_watching_ = false; | 235 is_watching_ = false; |
235 | 236 |
236 // Start watching for the next address change. | 237 // Start watching for the next address change. |
237 WatchForAddressChange(); | 238 WatchForAddressChange(); |
238 | 239 |
239 RecomputeCurrentConnectionTypeOnDnsThread(base::Bind( | 240 RecomputeCurrentConnectionTypeOnDnsThread(base::Bind( |
240 &NetworkChangeNotifierWin::NotifyObservers, weak_factory_.GetWeakPtr())); | 241 &NetworkChangeNotifierWin::NotifyObservers, weak_factory_.GetWeakPtr())); |
241 } | 242 } |
242 | 243 |
243 void NetworkChangeNotifierWin::NotifyObservers(ConnectionType connection_type) { | 244 void NetworkChangeNotifierWin::NotifyObservers(ConnectionType connection_type) { |
244 DCHECK(CalledOnValidThread()); | 245 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
245 SetCurrentConnectionType(connection_type); | 246 SetCurrentConnectionType(connection_type); |
246 NotifyObserversOfIPAddressChange(); | 247 NotifyObserversOfIPAddressChange(); |
247 | 248 |
248 // Calling GetConnectionType() at this very moment is likely to give | 249 // Calling GetConnectionType() at this very moment is likely to give |
249 // the wrong result, so we delay that until a little bit later. | 250 // the wrong result, so we delay that until a little bit later. |
250 // | 251 // |
251 // The one second delay chosen here was determined experimentally | 252 // The one second delay chosen here was determined experimentally |
252 // by adamk on Windows 7. | 253 // by adamk on Windows 7. |
253 // If after one second we determine we are still offline, we will | 254 // If after one second we determine we are still offline, we will |
254 // delay again. | 255 // delay again. |
255 offline_polls_ = 0; | 256 offline_polls_ = 0; |
256 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(1), this, | 257 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(1), this, |
257 &NetworkChangeNotifierWin::NotifyParentOfConnectionTypeChange); | 258 &NetworkChangeNotifierWin::NotifyParentOfConnectionTypeChange); |
258 } | 259 } |
259 | 260 |
260 void NetworkChangeNotifierWin::WatchForAddressChange() { | 261 void NetworkChangeNotifierWin::WatchForAddressChange() { |
261 DCHECK(CalledOnValidThread()); | 262 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
262 DCHECK(!is_watching_); | 263 DCHECK(!is_watching_); |
263 | 264 |
264 // NotifyAddrChange occasionally fails with ERROR_OPEN_FAILED for unknown | 265 // NotifyAddrChange occasionally fails with ERROR_OPEN_FAILED for unknown |
265 // reasons. More rarely, it's also been observed failing with | 266 // reasons. More rarely, it's also been observed failing with |
266 // ERROR_NO_SYSTEM_RESOURCES. When either of these happens, we retry later. | 267 // ERROR_NO_SYSTEM_RESOURCES. When either of these happens, we retry later. |
267 if (!WatchForAddressChangeInternal()) { | 268 if (!WatchForAddressChangeInternal()) { |
268 ++sequential_failures_; | 269 ++sequential_failures_; |
269 | 270 |
270 // TODO(mmenke): If the UMA histograms indicate that this fixes | 271 // TODO(mmenke): If the UMA histograms indicate that this fixes |
271 // http://crbug.com/69198, remove this histogram and consider reducing the | 272 // http://crbug.com/69198, remove this histogram and consider reducing the |
(...skipping 23 matching lines...) Expand all Loading... |
295 if (sequential_failures_ < 2000) { | 296 if (sequential_failures_ < 2000) { |
296 UMA_HISTOGRAM_COUNTS_10000("Net.NotifyAddrChangeFailures", | 297 UMA_HISTOGRAM_COUNTS_10000("Net.NotifyAddrChangeFailures", |
297 sequential_failures_); | 298 sequential_failures_); |
298 } | 299 } |
299 | 300 |
300 is_watching_ = true; | 301 is_watching_ = true; |
301 sequential_failures_ = 0; | 302 sequential_failures_ = 0; |
302 } | 303 } |
303 | 304 |
304 bool NetworkChangeNotifierWin::WatchForAddressChangeInternal() { | 305 bool NetworkChangeNotifierWin::WatchForAddressChangeInternal() { |
305 DCHECK(CalledOnValidThread()); | 306 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
306 | 307 |
307 if (!dns_config_service_thread_->IsRunning()) { | 308 if (!dns_config_service_thread_->IsRunning()) { |
308 dns_config_service_thread_->StartWithOptions( | 309 dns_config_service_thread_->StartWithOptions( |
309 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); | 310 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); |
310 } | 311 } |
311 | 312 |
312 ResetEventIfSignaled(addr_overlapped_.hEvent); | 313 ResetEventIfSignaled(addr_overlapped_.hEvent); |
313 HANDLE handle = NULL; | 314 HANDLE handle = NULL; |
314 DWORD ret = NotifyAddrChange(&handle, &addr_overlapped_); | 315 DWORD ret = NotifyAddrChange(&handle, &addr_overlapped_); |
315 if (ret != ERROR_IO_PENDING) | 316 if (ret != ERROR_IO_PENDING) |
(...skipping 29 matching lines...) Expand all Loading... |
345 | 346 |
346 NotifyObserversOfConnectionTypeChange(); | 347 NotifyObserversOfConnectionTypeChange(); |
347 double max_bandwidth_mbps = 0.0; | 348 double max_bandwidth_mbps = 0.0; |
348 ConnectionType max_connection_type = CONNECTION_NONE; | 349 ConnectionType max_connection_type = CONNECTION_NONE; |
349 GetCurrentMaxBandwidthAndConnectionType(&max_bandwidth_mbps, | 350 GetCurrentMaxBandwidthAndConnectionType(&max_bandwidth_mbps, |
350 &max_connection_type); | 351 &max_connection_type); |
351 NotifyObserversOfMaxBandwidthChange(max_bandwidth_mbps, max_connection_type); | 352 NotifyObserversOfMaxBandwidthChange(max_bandwidth_mbps, max_connection_type); |
352 } | 353 } |
353 | 354 |
354 } // namespace net | 355 } // namespace net |
OLD | NEW |