Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2006-2008 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 #ifndef NET_BASE_HOST_RESOLVER_IMPL_H_
      6 #define NET_BASE_HOST_RESOLVER_IMPL_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/scoped_ptr.h"
     12 #include "net/base/host_cache.h"
     13 #include "net/base/host_resolver.h"
     14 #include "net/base/host_resolver_proc.h"
     15 #include "net/base/network_change_notifier.h"
     16 
     17 namespace net {
     18 
     19 // For each hostname that is requested, HostResolver creates a
     20 // HostResolverImpl::Job. This job gets dispatched to a thread in the global
     21 // WorkerPool, where it runs SystemHostResolverProc(). If requests for that same
     22 // host are made while the job is already outstanding, then they are attached
     23 // to the existing job rather than creating a new one. This avoids doing
     24 // parallel resolves for the same host.
     25 //
     26 // The way these classes fit together is illustrated by:
     27 //
     28 //
     29 //            +----------- HostResolverImpl -------------+
     30 //            |                    |                     |
     31 //           Job                  Job                   Job
     32 //    (for host1, fam1)    (for host2, fam2)     (for hostx, famx)
     33 //       /    |   |            /   |   |             /   |   |
     34 //   Request ... Request  Request ... Request   Request ... Request
     35 //  (port1)     (port2)  (port3)      (port4)  (port5)      (portX)
     36 //
     37 //
     38 // When a HostResolverImpl::Job finishes its work in the threadpool, the
     39 // callbacks of each waiting request are run on the origin thread.
     40 //
     41 // Thread safety: This class is not threadsafe, and must only be called
     42 // from one thread!
     43 //
     44 // The HostResolverImpl enforces |max_jobs_| as the maximum number of concurrent
     45 // threads.
     46 //
     47 // Requests are ordered in the queue based on their priority.
     48 
     49 class HostResolverImpl : public HostResolver,
     50                          public NetworkChangeNotifier::Observer {
     51  public:
     52   // The index into |job_pools_| for the various job pools. Pools with a higher
     53   // index have lower priority.
     54   //
     55   // Note: This is currently unused, since there is a single pool
     56   //       for all requests.
     57   enum JobPoolIndex {
     58     POOL_NORMAL = 0,
     59     POOL_COUNT,
     60   };
     61 
     62   // Creates a HostResolver that first uses the local cache |cache|, and then
     63   // falls back to |resolver_proc|.
     64   //
     65   // If |cache| is NULL, then no caching is used. Otherwise we take
     66   // ownership of the |cache| pointer, and will free it during destructor.
     67   //
     68   // |resolver_proc| is used to perform the actual resolves; it must be
     69   // thread-safe since it is run from multiple worker threads. If
     70   // |resolver_proc| is NULL then the default host resolver procedure is
     71   // used (which is SystemHostResolverProc except if overridden).
     72   // |notifier| must outlive HostResolverImpl.  It can optionally be NULL, in
     73   // which case HostResolverImpl will not respond to network changes.
     74   // |max_jobs| specifies the maximum number of threads that the host resolver
     75   // will use. Use SetPoolConstraints() to specify finer-grain settings.
     76   HostResolverImpl(HostResolverProc* resolver_proc,
     77                    HostCache* cache,
     78                    NetworkChangeNotifier* notifier,
     79                    size_t max_jobs);
     80 
     81   // HostResolver methods:
     82   virtual int Resolve(const RequestInfo& info,
     83                       AddressList* addresses,
     84                       CompletionCallback* callback,
     85                       RequestHandle* out_req,
     86                       LoadLog* load_log);
     87   virtual void CancelRequest(RequestHandle req);
     88   virtual void AddObserver(HostResolver::Observer* observer);
     89   virtual void RemoveObserver(HostResolver::Observer* observer);
     90 
     91   // TODO(eroman): temp hack for http://crbug.com/15513
     92   virtual void Shutdown();
     93 
     94   virtual void SetDefaultAddressFamily(AddressFamily address_family) {
     95     default_address_family_ = address_family;
     96   }
     97 
     98   virtual bool IsHostResolverImpl() { return true; }
     99 
    100   // Returns the cache this resolver uses, or NULL if caching is disabled.
    101   HostCache* cache() { return cache_.get(); }
    102 
    103   // Clears the request trace log.
    104   void ClearRequestsTrace();
    105 
    106   // Starts/ends capturing requests to a trace log.
    107   void EnableRequestsTracing(bool enable);
    108 
    109   bool IsRequestsTracingEnabled() const;
    110 
    111   // Returns a copy of the requests trace log, or NULL if there is none.
    112   scoped_refptr<LoadLog> GetRequestsTrace();
    113 
    114   // Applies a set of constraints for requests that belong to the specified
    115   // pool. NOTE: Don't call this after requests have been already been started.
    116   //
    117   //  |pool_index| -- Specifies which pool these constraints should be applied
    118   //                  to.
    119   //  |max_outstanding_jobs| -- How many concurrent jobs are allowed for this
    120   //                            pool.
    121   //  |max_pending_requests| -- How many requests can be enqueued for this pool
    122   //                            before we start dropping requests. Dropped
    123   //                            requests fail with
    124   //                            ERR_HOST_RESOLVER_QUEUE_TOO_LARGE.
    125   void SetPoolConstraints(JobPoolIndex pool_index,
    126                           size_t max_outstanding_jobs,
    127                           size_t max_pending_requests);
    128 
    129  private:
    130   class Job;
    131   class JobPool;
    132   class Request;
    133   class RequestsTrace;
    134   typedef std::vector<Request*> RequestsList;
    135   typedef HostCache::Key Key;
    136   typedef std::map<Key, scoped_refptr<Job> > JobMap;
    137   typedef std::vector<HostResolver::Observer*> ObserversList;
    138 
    139   // If any completion callbacks are pending when the resolver is destroyed,
    140   // the host resolutions are cancelled, and the completion callbacks will not
    141   // be called.
    142   virtual ~HostResolverImpl();
    143 
    144   // Returns the HostResolverProc to use for this instance.
    145   HostResolverProc* effective_resolver_proc() const {
    146     return resolver_proc_ ?
    147         resolver_proc_.get() : HostResolverProc::GetDefault();
    148   }
    149 
    150   // Adds a job to outstanding jobs list.
    151   void AddOutstandingJob(Job* job);
    152 
    153   // Returns the outstanding job for |key|, or NULL if there is none.
    154   Job* FindOutstandingJob(const Key& key);
    155 
    156   // Removes |job| from the outstanding jobs list.
    157   void RemoveOutstandingJob(Job* job);
    158 
    159   // Callback for when |job| has completed with |error| and |addrlist|.
    160   void OnJobComplete(Job* job, int error, const AddressList& addrlist);
    161 
    162   // Called when a request has just been started.
    163   void OnStartRequest(LoadLog* load_log,
    164                       int request_id,
    165                       const RequestInfo& info);
    166 
    167   // Called when a request has just completed (before its callback is run).
    168   void OnFinishRequest(LoadLog* load_log,
    169                        int request_id,
    170                        const RequestInfo& info,
    171                        int error);
    172 
    173   // Called when a request has been cancelled.
    174   void OnCancelRequest(LoadLog* load_log,
    175                        int request_id,
    176                        const RequestInfo& info);
    177 
    178   // NetworkChangeNotifier::Observer methods:
    179   virtual void OnIPAddressChanged();
    180 
    181   // Returns true if the constraints for |pool| are met, and a new job can be
    182   // created for this pool.
    183   bool CanCreateJobForPool(const JobPool& pool) const;
    184 
    185   // Returns the index of the pool that request |req| maps to.
    186   static JobPoolIndex GetJobPoolIndexForRequest(const Request* req);
    187 
    188   JobPool* GetPoolForRequest(const Request* req) {
    189     return job_pools_[GetJobPoolIndexForRequest(req)];
    190   }
    191 
    192   // Starts up to 1 job given the current pool constraints. This job
    193   // may have multiple requests attached to it.
    194   void ProcessQueuedRequests();
    195 
    196   // Attaches |req| to a new job, and starts it. Returns that job.
    197   Job* CreateAndStartJob(Request* req);
    198 
    199   // Adds a pending request |req| to |pool|.
    200   int EnqueueRequest(JobPool* pool, Request* req);
    201 
    202   // Cache of host resolution results.
    203   scoped_ptr<HostCache> cache_;
    204 
    205   // Map from hostname to outstanding job.
    206   JobMap jobs_;
    207 
    208   // Maximum number of concurrent jobs allowed, across all pools.
    209   size_t max_jobs_;
    210 
    211   // The information to track pending requests for a JobPool, as well as
    212   // how many outstanding jobs the pool already has, and its constraints.
    213   JobPool* job_pools_[POOL_COUNT];
    214 
    215   // The job that OnJobComplete() is currently processing (needed in case
    216   // HostResolver gets deleted from within the callback).
    217   scoped_refptr<Job> cur_completing_job_;
    218 
    219   // The observers to notify when a request starts/ends.
    220   ObserversList observers_;
    221 
    222   // Monotonically increasing ID number to assign to the next request.
    223   // Observers are the only consumers of this ID number.
    224   int next_request_id_;
    225 
    226   // Monotonically increasing ID number to assign to the next job.
    227   // The only consumer of this ID is the requests tracing code.
    228   int next_job_id_;
    229 
    230   // The procedure to use for resolving host names. This will be NULL, except
    231   // in the case of unit-tests which inject custom host resolving behaviors.
    232   scoped_refptr<HostResolverProc> resolver_proc_;
    233 
    234   // Address family to use when the request doesn't specify one.
    235   AddressFamily default_address_family_;
    236 
    237   // TODO(eroman): temp hack for http://crbug.com/15513
    238   bool shutdown_;
    239 
    240   NetworkChangeNotifier* const network_change_notifier_;
    241 
    242   scoped_refptr<RequestsTrace> requests_trace_;
    243 
    244   DISALLOW_COPY_AND_ASSIGN(HostResolverImpl);
    245 };
    246 
    247 }  // namespace net
    248 
    249 #endif  // NET_BASE_HOST_RESOLVER_IMPL_H_
    250