Chromium Code Reviews| 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..8e04a051ff15679a70050be1792a3f1e19981719 |
| --- /dev/null |
| +++ b/net/dns/mojo_host_resolver_impl.cc |
| @@ -0,0 +1,133 @@ |
| +// 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/bind.h" |
| +#include "base/message_loop/message_loop.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/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(base::WeakPtr<MojoHostResolverImpl> resolver_service, |
| + net::HostResolver* resolver, |
| + const net::HostResolver::RequestInfo& request_info, |
| + interfaces::HostResolverRequestClientPtr client); |
| + ~Job() override; |
| + |
| + private: |
| + // Completion callback for the HostResolver::Resolve request. |
| + void OnResolveDone(int result); |
| + |
| + // Overridden from mojo::ErrorHandler: |
| + void OnConnectionError() override; |
| + |
| + base::WeakPtr<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), weak_factory_(this) { |
| +} |
| + |
| +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(weak_factory_.GetWeakPtr(), resolver_, |
| + request_info->To<net::HostResolver::RequestInfo>(), |
| + client.Pass()); |
| + pending_jobs_.insert(job); |
| +} |
| + |
| +void MojoHostResolverImpl::DeleteJob(Job* job) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + if (ContainsKey(pending_jobs_, job)) { |
| + size_t num_erased = pending_jobs_.erase(job); |
|
Sam McNally
2015/02/06 07:12:32
Please use the iterator erase overload. Doing two
Anand Mistry (off Chromium)
2015/02/08 23:09:21
I've gone back to having a Start() method. I reali
|
| + DCHECK(num_erased); |
| + delete job; |
| + } |
| +} |
| + |
| +MojoHostResolverImpl::Job::Job( |
| + base::WeakPtr<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); |
| + |
| + 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_) { |
| + VLOG(1) << address.ToString(); |
| + } |
| + if (result) |
| + client_->ReportResult(result, nullptr); |
| + else |
| + client_->ReportResult(0, interfaces::AddressList::From(result_)); |
| + |
| + // We could have been called inline with the constructor, so delay |
| + // destruction. |
| + base::MessageLoopProxy::current()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&MojoHostResolverImpl::DeleteJob, resolver_service_, 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 |