Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(300)

Side by Side Diff: net/base/network_change_notifier_mac.cc

Issue 9540011: [net] Add DNS-related signals and NetLog to NetworkChangeNotifier. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Moved DNS watch to a separate IO thread on mac. Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/network_change_notifier_mac.h ('k') | net/base/network_change_notifier_win.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_mac.h" 5 #include "net/base/network_change_notifier_mac.h"
6 6
7 #include <netinet/in.h> 7 #include <netinet/in.h>
8 #include <resolv.h>
9
10 #include "base/threading/thread.h"
11
12 #ifndef _PATH_RESCONF // Normally defined in <resolv.h>
13 #define _PATH_RESCONF "/etc/resolv.conf"
14 #endif
8 15
9 namespace net { 16 namespace net {
10 17
11 static bool CalculateReachability(SCNetworkConnectionFlags flags) { 18 static bool CalculateReachability(SCNetworkConnectionFlags flags) {
12 bool reachable = flags & kSCNetworkFlagsReachable; 19 bool reachable = flags & kSCNetworkFlagsReachable;
13 bool connection_required = flags & kSCNetworkFlagsConnectionRequired; 20 bool connection_required = flags & kSCNetworkFlagsConnectionRequired;
14 return reachable && !connection_required; 21 return reachable && !connection_required;
15 } 22 }
16 23
24 class NetworkChangeNotifierMac::DNSWatcher : public base::Thread {
25 public:
26 DNSWatcher() : watching_dns_(false) {}
27
28 virtual void Init() OVERRIDE {
29 base::AutoLock lock(watching_dns_lock_);
30 watching_dns_ = true;
31 if (!resolv_watcher_.Watch(
32 FilePath(FILE_PATH_LITERAL(_PATH_RESCONF)),
33 base::Bind(&DNSWatcher::OnDNSFileChanged,
34 base::Unretained(this),
35 static_cast<unsigned>(CHANGE_DNS_SETTINGS)))) {
36 LOG(ERROR) << "Failed to setup watch for /etc/resolv.conf";
37 watching_dns_ = false;
38 }
39 if (!hosts_watcher_.Watch(
40 FilePath(FILE_PATH_LITERAL("/etc/hosts")),
41 base::Bind(&DNSWatcher::OnDNSFileChanged,
42 base::Unretained(this),
43 static_cast<unsigned>(CHANGE_DNS_HOSTS)))) {
44 LOG(ERROR) << "Failed to setup watch for /etc/hosts";
45 watching_dns_ = false;
46 }
47 }
48
49 virtual void CleanUp() OVERRIDE {
50 base::AutoLock lock(watching_dns_lock_);
51 watching_dns_ = false;
52 resolv_watcher_.Cancel();
53 hosts_watcher_.Cancel();
54 }
55
56 bool IsWatching() const {
57 base::AutoLock lock(watching_dns_lock_);
58 return watching_dns_;
59 }
60
61 private:
62 // Called from FilePathWatcherCallback.
63 void OnDNSFileChanged(unsigned detail, bool watch_success) {
64 if (!watch_success) {
65 LOG(ERROR) << "DNS watch failed.";
66 base::AutoLock lock(watching_dns_lock_);
67 watching_dns_ = false;
68 }
69 // Always notify observers so that they can check IsWatchingDNS().
70 NetworkChangeNotifier::NotifyObserversOfDNSChange(detail);
71 }
72
73 FilePathWatcherCallback resolv_watcher_;
74 FilePathWatcherCallback hosts_watcher_;
75
76 bool watching_dns_;
77 mutable base::Lock watching_dns_lock_;
78 };
79
17 NetworkChangeNotifierMac::NetworkChangeNotifierMac() 80 NetworkChangeNotifierMac::NetworkChangeNotifierMac()
18 : online_state_(UNINITIALIZED), 81 : online_state_(UNINITIALIZED),
19 initial_state_cv_(&online_state_lock_), 82 initial_state_cv_(&online_state_lock_),
20 forwarder_(this) { 83 forwarder_(this) {
21 // Must be initialized after the rest of this object, as it may call back into 84 // Must be initialized after the rest of this object, as it may call back into
22 // SetInitialState(). 85 // SetInitialState().
23 config_watcher_.reset(new NetworkConfigWatcherMac(&forwarder_)); 86 config_watcher_.reset(new NetworkConfigWatcherMac(&forwarder_));
87
88 dns_watcher_.reset(new DNSWatcher());
89 dns_watcher_->StartWithOptions(
90 base::Thread::Options(MessageLoop::TYPE_IO, 0));
24 } 91 }
25 92
26 NetworkChangeNotifierMac::~NetworkChangeNotifierMac() { 93 NetworkChangeNotifierMac::~NetworkChangeNotifierMac() {
27 // Delete the ConfigWatcher to join the notifier thread, ensuring that 94 // Delete the ConfigWatcher to join the notifier thread, ensuring that
28 // StartReachabilityNotifications() has an opportunity to run to completion. 95 // StartReachabilityNotifications() has an opportunity to run to completion.
29 config_watcher_.reset(); 96 config_watcher_.reset();
30 97
31 // Now that StartReachabilityNotifications() has either run to completion or 98 // Now that StartReachabilityNotifications() has either run to completion or
32 // never run at all, unschedule reachability_ if it was previously scheduled. 99 // never run at all, unschedule reachability_ if it was previously scheduled.
33 if (reachability_.get() && run_loop_.get()) { 100 if (reachability_.get() && run_loop_.get()) {
34 SCNetworkReachabilityUnscheduleFromRunLoop(reachability_.get(), 101 SCNetworkReachabilityUnscheduleFromRunLoop(reachability_.get(),
35 run_loop_.get(), 102 run_loop_.get(),
36 kCFRunLoopCommonModes); 103 kCFRunLoopCommonModes);
37 } 104 }
38 } 105 }
39 106
40 bool NetworkChangeNotifierMac::IsCurrentlyOffline() const { 107 bool NetworkChangeNotifierMac::IsCurrentlyOffline() const {
41 base::AutoLock lock(online_state_lock_); 108 base::AutoLock lock(online_state_lock_);
42 // Make sure the initial state is set before returning. 109 // Make sure the initial state is set before returning.
43 while (online_state_ == UNINITIALIZED) { 110 while (online_state_ == UNINITIALIZED) {
44 initial_state_cv_.Wait(); 111 initial_state_cv_.Wait();
45 } 112 }
46 return online_state_ == OFFLINE; 113 return online_state_ == OFFLINE;
47 } 114 }
48 115
116 bool NetworkChangeNotifierMac::IsCurrentlyWatchingDNS() const {
117 return dns_watcher_->IsWatching();
118 }
119
49 void NetworkChangeNotifierMac::SetInitialState() { 120 void NetworkChangeNotifierMac::SetInitialState() {
50 // Called on notifier thread. 121 // Called on notifier thread.
51 122
52 // Try to reach 0.0.0.0. This is the approach taken by Firefox: 123 // Try to reach 0.0.0.0. This is the approach taken by Firefox:
53 // 124 //
54 // http://mxr.mozilla.org/mozilla2.0/source/netwerk/system/mac/nsNetworkLinkSe rvice.mm 125 // http://mxr.mozilla.org/mozilla2.0/source/netwerk/system/mac/nsNetworkLinkSe rvice.mm
55 // 126 //
56 // From my (adamk) testing on Snow Leopard, 0.0.0.0 127 // From my (adamk) testing on Snow Leopard, 0.0.0.0
57 // seems to be reachable if any network connection is available. 128 // seems to be reachable if any network connection is available.
58 struct sockaddr_in addr = {0}; 129 struct sockaddr_in addr = {0};
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 { 229 {
159 base::AutoLock lock(notifier_mac->online_state_lock_); 230 base::AutoLock lock(notifier_mac->online_state_lock_);
160 old_state = notifier_mac->online_state_; 231 old_state = notifier_mac->online_state_;
161 notifier_mac->online_state_ = new_state; 232 notifier_mac->online_state_ = new_state;
162 } 233 }
163 if (old_state != new_state) 234 if (old_state != new_state)
164 NotifyObserversOfOnlineStateChange(); 235 NotifyObserversOfOnlineStateChange();
165 } 236 }
166 237
167 } // namespace net 238 } // namespace net
OLDNEW
« no previous file with comments | « net/base/network_change_notifier_mac.h ('k') | net/base/network_change_notifier_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698