diff --git net/base/network_change_notifier_win.cc net/base/network_change_notifier_win.cc index 9b2b35e..1dc2038 100644 --- net/base/network_change_notifier_win.cc +++ net/base/network_change_notifier_win.cc @@ -14,6 +14,7 @@ #include "base/message_loop/message_loop.h" #include "base/metrics/histogram_macros.h" #include "base/single_thread_task_runner.h" +#include "base/task_runner_util.h" #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" @@ -136,8 +137,6 @@ NetworkChangeNotifierWin::NetworkChangeCalculatorParamsWin() { // NetworkChangeNotifier::ConnectionType NetworkChangeNotifierWin::RecomputeCurrentConnectionType() const { - DCHECK(CalledOnValidThread()); - EnsureWinsockInit(); // The following code was adapted from: @@ -205,6 +204,18 @@ NetworkChangeNotifierWin::RecomputeCurrentConnectionType() const { : NetworkChangeNotifier::CONNECTION_NONE; } +void NetworkChangeNotifierWin::RecomputeCurrentConnectionTypeOnDnsThread( + base::Callback reply_callback) const { + // Unretained is safe in this call because this object owns the thread and the + // thread is stopped in this object's destructor. + base::PostTaskAndReplyWithResult( + dns_config_service_thread_->message_loop()->task_runner().get(), + FROM_HERE, + base::Bind(&NetworkChangeNotifierWin::RecomputeCurrentConnectionType, + base::Unretained(this)), + reply_callback); +} + NetworkChangeNotifier::ConnectionType NetworkChangeNotifierWin::GetCurrentConnectionType() const { base::AutoLock auto_lock(last_computed_connection_type_lock_); @@ -225,12 +236,13 @@ void NetworkChangeNotifierWin::OnObjectSignaled(HANDLE object) { // Start watching for the next address change. WatchForAddressChange(); - NotifyObservers(); + RecomputeCurrentConnectionTypeOnDnsThread(base::Bind( + &NetworkChangeNotifierWin::NotifyObservers, weak_factory_.GetWeakPtr())); } -void NetworkChangeNotifierWin::NotifyObservers() { +void NetworkChangeNotifierWin::NotifyObservers(ConnectionType connection_type) { DCHECK(CalledOnValidThread()); - SetCurrentConnectionType(RecomputeCurrentConnectionType()); + SetCurrentConnectionType(connection_type); NotifyObserversOfIPAddressChange(); // Calling GetConnectionType() at this very moment is likely to give @@ -274,8 +286,11 @@ void NetworkChangeNotifierWin::WatchForAddressChange() { // Treat the transition from NotifyAddrChange failing to succeeding as a // network change event, since network changes were not being observed in // that interval. - if (sequential_failures_ > 0) - NotifyObservers(); + if (sequential_failures_ > 0) { + RecomputeCurrentConnectionTypeOnDnsThread( + base::Bind(&NetworkChangeNotifierWin::NotifyObservers, + weak_factory_.GetWeakPtr())); + } if (sequential_failures_ < 2000) { UMA_HISTOGRAM_COUNTS_10000("Net.NotifyAddrChangeFailures", @@ -305,7 +320,14 @@ bool NetworkChangeNotifierWin::WatchForAddressChangeInternal() { } void NetworkChangeNotifierWin::NotifyParentOfConnectionTypeChange() { - SetCurrentConnectionType(RecomputeCurrentConnectionType()); + RecomputeCurrentConnectionTypeOnDnsThread(base::Bind( + &NetworkChangeNotifierWin::NotifyParentOfConnectionTypeChangeImpl, + weak_factory_.GetWeakPtr())); +} + +void NetworkChangeNotifierWin::NotifyParentOfConnectionTypeChangeImpl( + ConnectionType connection_type) { + SetCurrentConnectionType(connection_type); bool current_offline = IsOffline(); offline_polls_++; // If we continue to appear offline, delay sending out the notification in @@ -323,10 +345,10 @@ void NetworkChangeNotifierWin::NotifyParentOfConnectionTypeChange() { NotifyObserversOfConnectionTypeChange(); double max_bandwidth_mbps = 0.0; - ConnectionType connection_type = CONNECTION_NONE; + ConnectionType max_connection_type = CONNECTION_NONE; GetCurrentMaxBandwidthAndConnectionType(&max_bandwidth_mbps, - &connection_type); - NotifyObserversOfMaxBandwidthChange(max_bandwidth_mbps, connection_type); + &max_connection_type); + NotifyObserversOfMaxBandwidthChange(max_bandwidth_mbps, max_connection_type); } } // namespace net diff --git net/base/network_change_notifier_win.h net/base/network_change_notifier_win.h index 94bab7f..6871499 100644 --- net/base/network_change_notifier_win.h +++ net/base/network_change_notifier_win.h @@ -9,6 +9,7 @@ #include +#include "base/callback.h" #include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -62,15 +63,21 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierWin // It is not thread safe, see crbug.com/324913. virtual ConnectionType RecomputeCurrentConnectionType() const; + // Calls RecomputeCurrentConnectionTypeImpl on the DNS thread and runs + // |reply_callback| with the type on the calling thread. + virtual void RecomputeCurrentConnectionTypeOnDnsThread( + base::Callback reply_callback) const; + void SetCurrentConnectionType(ConnectionType connection_type); // Notifies IP address change observers of a change immediately, and notifies // network state change observers on a delay. Must only be called on the // thread |this| was created on. - void NotifyObservers(); + void NotifyObservers(ConnectionType connection_type); // Forwards connection type notifications to parent class. void NotifyParentOfConnectionTypeChange(); + void NotifyParentOfConnectionTypeChangeImpl(ConnectionType connection_type); // Tries to start listening for a single subsequent address change. Returns // false on failure. The caller is responsible for updating |is_watching_|.