| Index: net/dns/mojo_host_resolver_impl.cc | 
| diff --git a/net/dns/mojo_host_resolver_impl.cc b/net/dns/mojo_host_resolver_impl.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..bf35f95e9d966d7bec5d8cd98673cd13ace47c79 | 
| --- /dev/null | 
| +++ b/net/dns/mojo_host_resolver_impl.cc | 
| @@ -0,0 +1,130 @@ | 
| +// Copyright 2015 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "net/dns/mojo_host_resolver_impl.h" | 
| + | 
| +#include "base/basictypes.h" | 
| +#include "base/stl_util.h" | 
| +#include "net/base/address_list.h" | 
| +#include "net/base/net_errors.h" | 
| +#include "net/dns/host_resolver.h" | 
| +#include "net/dns/mojo_type_converters.h" | 
| + | 
| +namespace net { | 
| + | 
| +// Handles host resolution for a single request and sends a response when done. | 
| +// Also detects connection errors for HostResolverRequestClient and cancels the | 
| +// outstanding resolve request. Owned by MojoHostResolverImpl. | 
| +class MojoHostResolverImpl::Job : public mojo::ErrorHandler { | 
| + public: | 
| +  Job(MojoHostResolverImpl* resolver_service, | 
| +      net::HostResolver* resolver, | 
| +      const net::HostResolver::RequestInfo& request_info, | 
| +      interfaces::HostResolverRequestClientPtr client); | 
| +  ~Job() override; | 
| + | 
| +  void Start(); | 
| + | 
| + private: | 
| +  // Completion callback for the HostResolver::Resolve request. | 
| +  void OnResolveDone(int result); | 
| + | 
| +  // Overridden from mojo::ErrorHandler: | 
| +  void OnConnectionError() override; | 
| + | 
| +  MojoHostResolverImpl* resolver_service_; | 
| +  net::HostResolver* resolver_; | 
| +  net::HostResolver::RequestInfo request_info_; | 
| +  interfaces::HostResolverRequestClientPtr client_; | 
| +  net::HostResolver::RequestHandle handle_; | 
| +  AddressList result_; | 
| +  base::ThreadChecker thread_checker_; | 
| +}; | 
| + | 
| +MojoHostResolverImpl::MojoHostResolverImpl(net::HostResolver* resolver) | 
| +    : resolver_(resolver) { | 
| +} | 
| + | 
| +MojoHostResolverImpl::~MojoHostResolverImpl() { | 
| +  DCHECK(thread_checker_.CalledOnValidThread()); | 
| +  STLDeleteElements(&pending_jobs_); | 
| +} | 
| + | 
| +void MojoHostResolverImpl::Resolve( | 
| +    interfaces::HostResolverRequestInfoPtr request_info, | 
| +    interfaces::HostResolverRequestClientPtr client) { | 
| +  DCHECK(thread_checker_.CalledOnValidThread()); | 
| +  Job* job = new Job(this, resolver_, | 
| +                     request_info->To<net::HostResolver::RequestInfo>(), | 
| +                     client.Pass()); | 
| +  pending_jobs_.insert(job); | 
| +  job->Start(); | 
| +} | 
| + | 
| +void MojoHostResolverImpl::DeleteJob(Job* job) { | 
| +  DCHECK(thread_checker_.CalledOnValidThread()); | 
| +  size_t num_erased = pending_jobs_.erase(job); | 
| +  DCHECK(num_erased); | 
| +  delete job; | 
| +} | 
| + | 
| +MojoHostResolverImpl::Job::Job( | 
| +    MojoHostResolverImpl* resolver_service, | 
| +    net::HostResolver* resolver, | 
| +    const net::HostResolver::RequestInfo& request_info, | 
| +    interfaces::HostResolverRequestClientPtr client) | 
| +    : resolver_service_(resolver_service), | 
| +      resolver_(resolver), | 
| +      request_info_(request_info), | 
| +      client_(client.Pass()), | 
| +      handle_(nullptr) { | 
| +  client_.set_error_handler(this); | 
| +} | 
| + | 
| +void MojoHostResolverImpl::Job::Start() { | 
| +  DVLOG(1) << "Resolve " << request_info_.host_port_pair().ToString(); | 
| +  BoundNetLog net_log; | 
| +  int result = | 
| +      resolver_->Resolve(request_info_, DEFAULT_PRIORITY, &result_, | 
| +                         base::Bind(&MojoHostResolverImpl::Job::OnResolveDone, | 
| +                                    base::Unretained(this)), | 
| +                         &handle_, net_log); | 
| + | 
| +  if (result != ERR_IO_PENDING) | 
| +    OnResolveDone(result); | 
| +} | 
| + | 
| +MojoHostResolverImpl::Job::~Job() { | 
| +  DCHECK(thread_checker_.CalledOnValidThread()); | 
| +  if (handle_) | 
| +    resolver_->CancelRequest(handle_); | 
| +} | 
| + | 
| +void MojoHostResolverImpl::Job::OnResolveDone(int result) { | 
| +  DCHECK(thread_checker_.CalledOnValidThread()); | 
| +  handle_ = nullptr; | 
| +  DVLOG(1) << "Resolved " << request_info_.host_port_pair().ToString() | 
| +           << " with error " << result << " and " << result_.size() | 
| +           << " results!"; | 
| +  for (const auto& address : result_) { | 
| +    DVLOG(1) << address.ToString(); | 
| +  } | 
| +  if (result == OK) | 
| +    client_->ReportResult(result, interfaces::AddressList::From(result_)); | 
| +  else | 
| +    client_->ReportResult(result, nullptr); | 
| + | 
| +  resolver_service_->DeleteJob(this); | 
| +} | 
| + | 
| +void MojoHostResolverImpl::Job::OnConnectionError() { | 
| +  DCHECK(thread_checker_.CalledOnValidThread()); | 
| +  // |resolver_service_| should always outlive us. | 
| +  DCHECK(resolver_service_); | 
| +  DVLOG(1) << "Connection error on request for " | 
| +           << request_info_.host_port_pair().ToString(); | 
| +  resolver_service_->DeleteJob(this); | 
| +} | 
| + | 
| +}  // namespace net | 
|  |