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

Unified Diff: net/base/network_change_notifier_linux.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, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/base/network_change_notifier_linux.h ('k') | net/base/network_change_notifier_mac.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/base/network_change_notifier_linux.cc
diff --git a/net/base/network_change_notifier_linux.cc b/net/base/network_change_notifier_linux.cc
index 92eec2d0044f115329376692e170b8b86722865e..be6f3dabb6cd16ef748009fbb67a5342f2731725 100644
--- a/net/base/network_change_notifier_linux.cc
+++ b/net/base/network_change_notifier_linux.cc
@@ -10,6 +10,7 @@
#include "net/base/network_change_notifier_linux.h"
#include <errno.h>
+#include <resolv.h>
#include <sys/socket.h>
#include "base/bind.h"
@@ -27,11 +28,16 @@
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_proxy.h"
+#include "net/base/file_path_watcher_callback.h"
#include "net/base/net_errors.h"
#include "net/base/network_change_notifier_netlink_linux.h"
using ::base::files::FilePathWatcher;
+#ifndef _PATH_RESCONF // Normally defined in <resolv.h>
+#define _PATH_RESCONF "/etc/resolv.conf"
+#endif
+
namespace net {
namespace {
@@ -237,28 +243,6 @@ bool NetworkManagerApi::IsCurrentlyOffline() {
return is_offline_;
}
-class DNSWatchDelegate : public FilePathWatcher::Delegate {
- public:
- explicit DNSWatchDelegate(const base::Closure& callback)
- : callback_(callback) {}
- virtual ~DNSWatchDelegate() {}
- // FilePathWatcher::Delegate interface
- virtual void OnFilePathChanged(const FilePath& path) OVERRIDE;
- virtual void OnFilePathError(const FilePath& path) OVERRIDE;
- private:
- base::Closure callback_;
- DISALLOW_COPY_AND_ASSIGN(DNSWatchDelegate);
-};
-
-void DNSWatchDelegate::OnFilePathChanged(const FilePath& path) {
- // Calls NetworkChangeNotifier::NotifyObserversOfDNSChange().
- callback_.Run();
-}
-
-void DNSWatchDelegate::OnFilePathError(const FilePath& path) {
- LOG(ERROR) << "DNSWatchDelegate::OnFilePathError for " << path.value();
-}
-
} // namespace
class NetworkChangeNotifierLinux::Thread
@@ -277,6 +261,11 @@ class NetworkChangeNotifierLinux::Thread
return network_manager_api_.IsCurrentlyOffline();
}
+ bool IsCurrentlyWatchingDNS() {
+ base::AutoLock lock(watching_dns_lock_);
+ return watching_dns_;
+ }
+
protected:
// base::Thread
virtual void Init();
@@ -292,18 +281,19 @@ class NetworkChangeNotifierLinux::Thread
// recv() would block. Otherwise, it returns a net error code.
int ReadNotificationMessage(char* buf, size_t len);
+ // Called from FilePathWatcherCallback.
+ void OnDNSFileChanged(unsigned detail, bool watch_success);
+
// The netlink socket descriptor.
int netlink_fd_;
MessageLoopForIO::FileDescriptorWatcher netlink_watcher_;
- // Technically only needed for ChromeOS, but it's ugly to #ifdef out.
- base::WeakPtrFactory<Thread> ptr_factory_;
-
// Used to watch for changes to /etc/resolv.conf and /etc/hosts.
- scoped_ptr<base::files::FilePathWatcher> resolv_file_watcher_;
- scoped_ptr<base::files::FilePathWatcher> hosts_file_watcher_;
- scoped_refptr<DNSWatchDelegate> resolv_watcher_delegate_;
- scoped_refptr<DNSWatchDelegate> hosts_watcher_delegate_;
+ FilePathWatcherCallback resolv_watcher_;
+ FilePathWatcherCallback hosts_watcher_;
+
+ base::Lock watching_dns_lock_;
+ bool watching_dns_;
// Used to detect online/offline state changes.
NetworkManagerApi network_manager_api_;
@@ -314,7 +304,7 @@ class NetworkChangeNotifierLinux::Thread
NetworkChangeNotifierLinux::Thread::Thread(dbus::Bus* bus)
: base::Thread("NetworkChangeNotifier"),
netlink_fd_(kInvalidSocket),
- ALLOW_THIS_IN_INITIALIZER_LIST(ptr_factory_(this)),
+ watching_dns_(false),
network_manager_api_(
base::Bind(&NetworkChangeNotifier
::NotifyObserversOfOnlineStateChange),
@@ -326,22 +316,23 @@ NetworkChangeNotifierLinux::Thread::~Thread() {
}
void NetworkChangeNotifierLinux::Thread::Init() {
- resolv_file_watcher_.reset(new FilePathWatcher);
- hosts_file_watcher_.reset(new FilePathWatcher);
- resolv_watcher_delegate_ = new DNSWatchDelegate(base::Bind(
- &NetworkChangeNotifier::NotifyObserversOfDNSChange,
- static_cast<unsigned>(CHANGE_DNS_SETTINGS)));
- hosts_watcher_delegate_ = new DNSWatchDelegate(base::Bind(
- &NetworkChangeNotifier::NotifyObserversOfDNSChange,
- static_cast<unsigned>(CHANGE_DNS_HOSTS)));
- if (!resolv_file_watcher_->Watch(
- FilePath(FILE_PATH_LITERAL("/etc/resolv.conf")),
- resolv_watcher_delegate_.get())) {
+ base::AutoLock lock(watching_dns_lock_);
+ watching_dns_ = true;
+ if (!resolv_watcher_.Watch(
+ FilePath(FILE_PATH_LITERAL(_PATH_RESCONF)),
+ base::Bind(&Thread::OnDNSFileChanged,
+ base::Unretained(this),
+ static_cast<unsigned>(CHANGE_DNS_SETTINGS)))) {
LOG(ERROR) << "Failed to setup watch for /etc/resolv.conf";
+ watching_dns_ = false;
}
- if (!hosts_file_watcher_->Watch(FilePath(FILE_PATH_LITERAL("/etc/hosts")),
- hosts_watcher_delegate_.get())) {
+ if (!hosts_watcher_.Watch(
+ FilePath(FILE_PATH_LITERAL("/etc/hosts")),
+ base::Bind(&Thread::OnDNSFileChanged,
+ base::Unretained(this),
+ static_cast<unsigned>(CHANGE_DNS_HOSTS)))) {
LOG(ERROR) << "Failed to setup watch for /etc/hosts";
+ watching_dns_ = false;
}
netlink_fd_ = InitializeNetlinkSocket();
if (netlink_fd_ < 0) {
@@ -362,8 +353,8 @@ void NetworkChangeNotifierLinux::Thread::CleanUp() {
}
// Kill watchers early to make sure they won't try to call
// into us via the delegate during destruction.
- resolv_file_watcher_.reset();
- hosts_file_watcher_.reset();
+ resolv_watcher_.Cancel();
+ hosts_watcher_.Cancel();
network_manager_api_.CleanUp();
}
@@ -384,19 +375,7 @@ void NetworkChangeNotifierLinux::Thread::ListenForNotifications() {
while (rv > 0) {
if (HandleNetlinkMessage(buf, rv)) {
VLOG(1) << "Detected IP address changes.";
-#if defined(OS_CHROMEOS)
- // TODO(oshima): chromium-os:8285 - introduced artificial delay to
- // work around the issue of network load issue after connection
- // restored. See the bug for more details.
- // This should be removed once this bug is properly fixed.
- const int kObserverNotificationDelayMS = 200;
- message_loop()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&NetworkChangeNotifier::NotifyObserversOfIPAddressChange),
- kObserverNotificationDelayMS);
-#else
NotifyObserversOfIPAddressChange();
-#endif
}
rv = ReadNotificationMessage(buf, arraysize(buf));
}
@@ -427,6 +406,17 @@ int NetworkChangeNotifierLinux::Thread::ReadNotificationMessage(
return ERR_IO_PENDING;
}
+void NetworkChangeNotifierLinux::Thread::OnDNSFileChanged(unsigned detail,
+ bool watch_success) {
+ if (!watch_success) {
+ LOG(ERROR) << "DNS watch failed.";
+ base::AutoLock lock(watching_dns_lock_);
+ watching_dns_ = false;
+ }
+ // Always notify observers so that they can check IsWatchingDNS().
+ NetworkChangeNotifier::NotifyObserversOfDNSChange(detail);
+}
+
NetworkChangeNotifierLinux* NetworkChangeNotifierLinux::Create() {
return new NetworkChangeNotifierLinux(NULL);
}
@@ -455,4 +445,8 @@ bool NetworkChangeNotifierLinux::IsCurrentlyOffline() const {
return notifier_thread_->IsCurrentlyOffline();
}
+bool NetworkChangeNotifierLinux::IsCurrentlyWatchingDNS() const {
+ return notifier_thread_->IsCurrentlyWatchingDNS();
+}
+
} // namespace net
« no previous file with comments | « net/base/network_change_notifier_linux.h ('k') | net/base/network_change_notifier_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698