| 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 |