Home | History | Annotate | Download | only in dns
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/dns/single_request_host_resolver.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/bind_helpers.h"
      9 #include "base/compiler_specific.h"
     10 #include "base/logging.h"
     11 #include "net/base/net_errors.h"
     12 
     13 namespace net {
     14 
     15 SingleRequestHostResolver::SingleRequestHostResolver(HostResolver* resolver)
     16     : resolver_(resolver),
     17       cur_request_(NULL),
     18       callback_(
     19           base::Bind(&SingleRequestHostResolver::OnResolveCompletion,
     20                      base::Unretained(this))) {
     21   DCHECK(resolver_ != NULL);
     22 }
     23 
     24 SingleRequestHostResolver::~SingleRequestHostResolver() {
     25   Cancel();
     26 }
     27 
     28 int SingleRequestHostResolver::Resolve(const HostResolver::RequestInfo& info,
     29                                        RequestPriority priority,
     30                                        AddressList* addresses,
     31                                        const CompletionCallback& callback,
     32                                        const BoundNetLog& net_log) {
     33   DCHECK(addresses);
     34   DCHECK_EQ(false, callback.is_null());
     35   DCHECK(cur_request_callback_.is_null()) << "resolver already in use";
     36 
     37   HostResolver::RequestHandle request = NULL;
     38 
     39   // We need to be notified of completion before |callback| is called, so that
     40   // we can clear out |cur_request_*|.
     41   CompletionCallback transient_callback =
     42       callback.is_null() ? CompletionCallback() : callback_;
     43 
     44   int rv = resolver_->Resolve(
     45       info, priority, addresses, transient_callback, &request, net_log);
     46 
     47   if (rv == ERR_IO_PENDING) {
     48     DCHECK_EQ(false, callback.is_null());
     49     // Cleared in OnResolveCompletion().
     50     cur_request_ = request;
     51     cur_request_callback_ = callback;
     52   }
     53 
     54   return rv;
     55 }
     56 
     57 void SingleRequestHostResolver::Cancel() {
     58   if (!cur_request_callback_.is_null()) {
     59     resolver_->CancelRequest(cur_request_);
     60     cur_request_ = NULL;
     61     cur_request_callback_.Reset();
     62   }
     63 }
     64 
     65 void SingleRequestHostResolver::OnResolveCompletion(int result) {
     66   DCHECK(cur_request_);
     67   DCHECK_EQ(false, cur_request_callback_.is_null());
     68 
     69   CompletionCallback callback = cur_request_callback_;
     70 
     71   // Clear the outstanding request information.
     72   cur_request_ = NULL;
     73   cur_request_callback_.Reset();
     74 
     75   // Call the user's original callback.
     76   callback.Run(result);
     77 }
     78 
     79 }  // namespace net
     80