| Index: net/base/host_resolver.h
|
| ===================================================================
|
| --- net/base/host_resolver.h (revision 18213)
|
| +++ net/base/host_resolver.h (working copy)
|
| @@ -6,34 +6,73 @@
|
| #define NET_BASE_HOST_RESOLVER_H_
|
|
|
| #include <string>
|
| +#include <vector>
|
|
|
| #include "base/basictypes.h"
|
| +#include "base/lock.h"
|
| #include "base/ref_counted.h"
|
| #include "net/base/completion_callback.h"
|
| +#include "net/base/host_cache.h"
|
|
|
| +class MessageLoop;
|
| +
|
| namespace net {
|
|
|
| class AddressList;
|
| +class HostMapper;
|
|
|
| -// This class represents the task of resolving a hostname (or IP address
|
| -// literal) to an AddressList object. It can only resolve a single hostname at
|
| -// a time, so if you need to resolve multiple hostnames at the same time, you
|
| -// will need to allocate a HostResolver object for each hostname.
|
| +// This class represents the task of resolving hostnames (or IP address
|
| +// literal) to an AddressList object.
|
| //
|
| -// No attempt is made at this level to cache or pin resolution results. For
|
| -// each request, this API talks directly to the underlying name resolver of
|
| -// the local system, which may or may not result in a DNS query. The exact
|
| -// behavior depends on the system configuration.
|
| +// HostResolver handles multiple requests at a time, so when cancelling a
|
| +// request the Request* handle that was returned by Resolve() needs to be
|
| +// given. A simpler alternative for consumers that only have 1 outstanding
|
| +// request at a time is to create a SingleRequestHostResolver wrapper around
|
| +// HostResolver (which will automatically cancel the single request when it
|
| +// goes out of scope).
|
| //
|
| +// For each hostname that is requested, HostResolver creates a
|
| +// HostResolver::Job. This job gets dispatched to a thread in the global
|
| +// WorkerPool, where it runs "getaddrinfo(hostname)". If requests for that same
|
| +// host are made while the job is already outstanding, then they are attached
|
| +// to the existing job rather than creating a new one. This avoids doing
|
| +// parallel resolves for the same host.
|
| +//
|
| +// The way these classes fit together is illustrated by:
|
| +//
|
| +//
|
| +// +------------- HostResolver ---------------+
|
| +// | | |
|
| +// Job Job Job
|
| +// (for host1) (for host2) (for hostX)
|
| +// / | | / | | / | |
|
| +// Request ... Request Request ... Request Request ... Request
|
| +// (port1) (port2) (port3) (port4) (port5) (portX)
|
| +//
|
| +//
|
| +// When a HostResolver::Job finishes its work in the threadpool, the callbacks
|
| +// of each waiting request are run on the origin thread.
|
| +//
|
| +// Thread safety: This class is not threadsafe, and must only be called
|
| +// from one thread!
|
| +//
|
| class HostResolver {
|
| public:
|
| - HostResolver();
|
| + // Creates a HostResolver that caches up to |max_cache_entries| for
|
| + // |cache_duration_ms| milliseconds.
|
| + //
|
| + // TODO(eroman): Get rid of the default parameters as it violate google
|
| + // style. This is temporary to help with refactoring.
|
| + HostResolver(int max_cache_entries = 100, int cache_duration_ms = 60000);
|
|
|
| - // If a completion callback is pending when the resolver is destroyed, the
|
| - // host resolution is cancelled, and the completion callback will not be
|
| - // called.
|
| + // If any completion callbacks are pending when the resolver is destroyed,
|
| + // the host resolutions are cancelled, and the completion callbacks will not
|
| + // be called.
|
| ~HostResolver();
|
|
|
| + // Opaque type used to cancel a request.
|
| + class Request;
|
| +
|
| // Resolves the given hostname (or IP address literal), filling out the
|
| // |addresses| object upon success. The |port| parameter will be set as the
|
| // sin(6)_port field of the sockaddr_in{6} struct. Returns OK if successful
|
| @@ -43,17 +82,82 @@
|
| //
|
| // When callback is non-null, the operation will be performed asynchronously.
|
| // ERR_IO_PENDING is returned if it has been scheduled successfully. Real
|
| - // result code will be passed to the completion callback.
|
| + // result code will be passed to the completion callback. If |req| is
|
| + // non-NULL, then |*req| will be filled with a handle to the async request.
|
| + // This handle is not valid after the request has completed.
|
| int Resolve(const std::string& hostname, int port,
|
| - AddressList* addresses, CompletionCallback* callback);
|
| + AddressList* addresses, CompletionCallback* callback,
|
| + Request** req);
|
|
|
| + // Cancels the specified request. |req| is the handle returned by Resolve().
|
| + // After a request is cancelled, its completion callback will not be called.
|
| + void CancelRequest(Request* req);
|
| +
|
| private:
|
| - class Request;
|
| - friend class Request;
|
| - scoped_refptr<Request> request_;
|
| + class Job;
|
| + typedef std::vector<Request*> RequestsList;
|
| + typedef base::hash_map<std::string, scoped_refptr<Job> > JobMap;
|
| +
|
| + // Adds a job to outstanding jobs list.
|
| + void AddOutstandingJob(Job* job);
|
| +
|
| + // Returns the outstanding job for |hostname|, or NULL if there is none.
|
| + Job* FindOutstandingJob(const std::string& hostname);
|
| +
|
| + // Removes |job| from the outstanding jobs list.
|
| + void RemoveOutstandingJob(Job* job);
|
| +
|
| + // Callback for when |job| has completed with |error| and |addrlist|.
|
| + void OnJobComplete(Job* job, int error, const AddressList& addrlist);
|
| +
|
| + // Cache of host resolution results.
|
| + HostCache cache_;
|
| +
|
| + // Map from hostname to outstanding job.
|
| + JobMap jobs_;
|
| +
|
| + // The job that OnJobComplete() is currently processing (needed in case
|
| + // HostResolver gets deleted from within the callback).
|
| + scoped_refptr<Job> cur_completing_job_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(HostResolver);
|
| };
|
|
|
| +// This class represents the task of resolving a hostname (or IP address
|
| +// literal) to an AddressList object. It wraps HostResolver to resolve only a
|
| +// single hostname at a time and cancels this request when going out of scope.
|
| +class SingleRequestHostResolver {
|
| + public:
|
| + explicit SingleRequestHostResolver(HostResolver* resolver);
|
| +
|
| + // If a completion callback is pending when the resolver is destroyed, the
|
| + // host resolution is cancelled, and the completion callback will not be
|
| + // called.
|
| + ~SingleRequestHostResolver();
|
| +
|
| + // Resolves the given hostname (or IP address literal), filling out the
|
| + // |addresses| object upon success. See HostResolver::Resolve() for details.
|
| + int Resolve(const std::string& hostname, int port,
|
| + AddressList* addresses, CompletionCallback* callback);
|
| +
|
| + private:
|
| + // Callback for when the request to |resolver_| completes, so we dispatch
|
| + // to the user's callback.
|
| + void OnResolveCompletion(int result);
|
| +
|
| + // The actual host resolver that will handle the request.
|
| + HostResolver* resolver_;
|
| +
|
| + // The current request (if any).
|
| + HostResolver::Request* cur_request_;
|
| + CompletionCallback* cur_request_callback_;
|
| +
|
| + // Completion callback for when request to |resolver_| completes.
|
| + net::CompletionCallbackImpl<SingleRequestHostResolver> callback_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(SingleRequestHostResolver);
|
| +};
|
| +
|
| // A helper class used in unit tests to alter hostname mappings. See
|
| // SetHostMapper for details.
|
| class HostMapper : public base::RefCountedThreadSafe<HostMapper> {
|
|
|