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

Unified Diff: net/base/host_resolver_impl.cc

Issue 1006001: Refine IPv6 probe to require that the client has an IPv6 address on an interf... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/base/host_resolver_impl.h ('k') | net/base/net_util.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/base/host_resolver_impl.cc
===================================================================
--- net/base/host_resolver_impl.cc (revision 41742)
+++ net/base/host_resolver_impl.cc (working copy)
@@ -21,6 +21,7 @@
#include "net/base/host_resolver_proc.h"
#include "net/base/net_log.h"
#include "net/base/net_errors.h"
+#include "net/base/net_util.h"
#include "net/base/network_change_notifier.h"
#if defined(OS_WIN)
@@ -192,7 +193,8 @@
public:
Job(int id, HostResolverImpl* resolver, const Key& key,
RequestsTrace* requests_trace)
- : id_(id), key_(key),
+ : id_(id),
+ key_(key),
resolver_(resolver),
origin_loop_(MessageLoop::current()),
resolver_proc_(resolver->effective_resolver_proc()),
@@ -421,6 +423,91 @@
//-----------------------------------------------------------------------------
+// This class represents a request to the worker pool for a "probe for IPv6
+// support" call.
+class HostResolverImpl::IPv6ProbeJob
+ : public base::RefCountedThreadSafe<HostResolverImpl::IPv6ProbeJob> {
+ public:
+ explicit IPv6ProbeJob(HostResolverImpl* resolver)
+ : resolver_(resolver),
+ origin_loop_(MessageLoop::current()) {
+ }
+
+ void Start() {
+ DCHECK(IsOnOriginThread());
+ const bool IS_SLOW = true;
+ WorkerPool::PostTask(
+ FROM_HERE, NewRunnableMethod(this, &IPv6ProbeJob::DoProbe), IS_SLOW);
+ }
+
+ // Cancels the current job.
+ void Cancel() {
+ DCHECK(IsOnOriginThread());
+ resolver_ = NULL; // Read/write ONLY on origin thread.
+ {
+ AutoLock locked(origin_loop_lock_);
+ // Origin loop may be destroyed before we can use it!
+ origin_loop_ = NULL;
+ }
+ }
+
+ bool was_cancelled() const {
+ DCHECK(IsOnOriginThread());
+ return resolver_ == NULL;
+ }
+
+ private:
+ friend class base::RefCountedThreadSafe<HostResolverImpl::IPv6ProbeJob>;
+
+ ~IPv6ProbeJob() {
+ }
+
+ // Run on worker thread.
+ void DoProbe() {
+ // Do actual testing on this thread, as it takes 40-100ms.
+ AddressFamily family = IPv6Supported() ? ADDRESS_FAMILY_UNSPECIFIED
+ : ADDRESS_FAMILY_IPV4;
+
+ Task* reply = NewRunnableMethod(this, &IPv6ProbeJob::OnProbeComplete,
+ family);
+
+ // The origin loop could go away while we are trying to post to it, so we
+ // need to call its PostTask method inside a lock. See ~HostResolver.
+ {
+ AutoLock locked(origin_loop_lock_);
+ if (origin_loop_) {
+ origin_loop_->PostTask(FROM_HERE, reply);
+ return;
+ }
+ }
+
+ // We didn't post, so delete the reply.
+ delete reply;
+ }
+
+ // Callback for when DoProbe() completes (runs on origin thread).
+ void OnProbeComplete(AddressFamily address_family) {
+ DCHECK(IsOnOriginThread());
+ if (!was_cancelled())
+ resolver_->IPv6ProbeSetDefaultAddressFamily(address_family);
+ }
+
+ bool IsOnOriginThread() const {
+ return !MessageLoop::current() || origin_loop_ == MessageLoop::current();
+ }
+
+ // Used/set only on origin thread.
+ HostResolverImpl* resolver_;
+
+ // Used to post ourselves onto the origin thread.
+ Lock origin_loop_lock_;
+ MessageLoop* origin_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(IPv6ProbeJob);
+};
+
+//-----------------------------------------------------------------------------
+
// We rely on the priority enum values being sequential having starting at 0,
// and increasing for lower priorities.
COMPILE_ASSERT(HIGHEST == 0u &&
@@ -581,7 +668,8 @@
resolver_proc_(resolver_proc),
default_address_family_(ADDRESS_FAMILY_UNSPECIFIED),
shutdown_(false),
- network_change_notifier_(network_change_notifier) {
+ network_change_notifier_(network_change_notifier),
+ ipv6_probe_monitoring_(false) {
DCHECK_GT(max_jobs, 0u);
// It is cumbersome to expose all of the constraints in the constructor,
@@ -598,6 +686,8 @@
HostResolverImpl::~HostResolverImpl() {
// Cancel the outstanding jobs. Those jobs may contain several attached
// requests, which will also be cancelled.
+ DiscardIPv6ProbeJob();
+
for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ++it)
it->second->Cancel();
@@ -742,6 +832,18 @@
observers_.erase(it);
}
+void HostResolverImpl::SetDefaultAddressFamily(AddressFamily address_family) {
+ ipv6_probe_monitoring_ = false;
+ DiscardIPv6ProbeJob();
+ default_address_family_ = address_family;
+}
+
+void HostResolverImpl::ProbeIPv6Support() {
+ DCHECK(!ipv6_probe_monitoring_);
+ ipv6_probe_monitoring_ = true;
+ OnIPAddressChanged(); // Give initial setup call.
+}
+
void HostResolverImpl::Shutdown() {
shutdown_ = true;
@@ -975,8 +1077,34 @@
void HostResolverImpl::OnIPAddressChanged() {
if (cache_.get())
cache_->clear();
+ if (ipv6_probe_monitoring_) {
+ DiscardIPv6ProbeJob();
+ ipv6_probe_job_ = new IPv6ProbeJob(this);
+ ipv6_probe_job_->Start();
+ }
}
+void HostResolverImpl::DiscardIPv6ProbeJob() {
+ if (ipv6_probe_job_.get()) {
+ ipv6_probe_job_->Cancel();
+ ipv6_probe_job_ = NULL;
+ }
+}
+
+void HostResolverImpl::IPv6ProbeSetDefaultAddressFamily(
+ AddressFamily address_family) {
+ DCHECK(address_family == ADDRESS_FAMILY_UNSPECIFIED ||
+ address_family == ADDRESS_FAMILY_IPV4);
+ if (default_address_family_ != address_family)
+ LOG(INFO) << "IPv6Probe forced AddressFamily setting to "
+ << ((address_family == ADDRESS_FAMILY_UNSPECIFIED)
+ ? "ADDRESS_FAMILY_UNSPECIFIED"
+ : "ADDRESS_FAMILY_IPV4");
+ default_address_family_ = address_family;
+ // Drop reference since the job has called us back.
+ DiscardIPv6ProbeJob();
+}
+
// static
HostResolverImpl::JobPoolIndex HostResolverImpl::GetJobPoolIndexForRequest(
const Request* req) {
« no previous file with comments | « net/base/host_resolver_impl.h ('k') | net/base/net_util.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698