Relands r58007.
Fixes the problem with the flaky unittest that happened due to message loop posting race conditions.
BUG=53386
TEST=HostResolverImplTest.AbortOnIPAddressChanged,HostResolverImplTest.OnlyAbortExistingRequestsOnIPAddressChange

Review URL: http://codereview.chromium.org/3231013

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58171 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/net/base/host_resolver_impl.cc b/net/base/host_resolver_impl.cc
index f4f7bbd..b93ae31 100644
--- a/net/base/host_resolver_impl.cc
+++ b/net/base/host_resolver_impl.cc
@@ -258,7 +258,9 @@
   void OnComplete(int error, const AddressList& addrlist) {
     if (error == OK)
       addresses_->SetFrom(addrlist, port());
-    callback_->Run(error);
+    CompletionCallback* callback = callback_;
+    MarkAsCancelled();
+    callback->Run(error);
   }
 
   int port() const {
@@ -840,8 +842,7 @@
   // requests, which will also be cancelled.
   DiscardIPv6ProbeJob();
 
-  for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ++it)
-    it->second->Cancel();
+  CancelAllJobs();
 
   // In case we are being deleted during the processing of a callback.
   if (cur_completing_job_)
@@ -1035,9 +1036,7 @@
   DCHECK(CalledOnValidThread());
 
   // Cancel the outstanding jobs.
-  for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ++it)
-    it->second->Cancel();
-  jobs_.clear();
+  CancelAllJobs();
   DiscardIPv6ProbeJob();
 
   shutdown_ = true;
@@ -1090,6 +1089,18 @@
   if (cache_.get())
     cache_->Set(job->key(), net_error, addrlist, base::TimeTicks::Now());
 
+  OnJobCompleteInternal(job, net_error, os_error, addrlist);
+}
+
+void HostResolverImpl::AbortJob(Job* job) {
+  OnJobCompleteInternal(job, ERR_ABORTED, 0 /* no os_error */, AddressList());
+}
+
+void HostResolverImpl::OnJobCompleteInternal(
+    Job* job,
+    int net_error,
+    int os_error,
+    const AddressList& addrlist) {
   // Make a note that we are executing within OnJobComplete() in case the
   // HostResolver is deleted by a callback invocation.
   DCHECK(!cur_completing_job_);
@@ -1199,6 +1210,7 @@
     ipv6_probe_job_ = new IPv6ProbeJob(this);
     ipv6_probe_job_->Start();
   }
+  AbortAllJobs();
 #if defined(OS_LINUX)
   if (HaveOnlyLoopbackAddresses()) {
     additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY;
@@ -1317,4 +1329,20 @@
   return ERR_IO_PENDING;
 }
 
+void HostResolverImpl::CancelAllJobs() {
+  JobMap jobs;
+  jobs.swap(jobs_);
+  for (JobMap::iterator it = jobs.begin(); it != jobs.end(); ++it)
+    it->second->Cancel();
+}
+
+void HostResolverImpl::AbortAllJobs() {
+  JobMap jobs;
+  jobs.swap(jobs_);
+  for (JobMap::iterator it = jobs.begin(); it != jobs.end(); ++it) {
+    AbortJob(it->second);
+    it->second->Cancel();
+  }
+}
+
 }  // namespace net