Home | History | Annotate | Download | only in proxy
      1 // Copyright (c) 2009 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_PROXY_SINGLE_THREADED_PROXY_RESOLVER_H_
      6 #define NET_PROXY_SINGLE_THREADED_PROXY_RESOLVER_H_
      7 
      8 #include <deque>
      9 #include <string>
     10 
     11 #include "base/ref_counted.h"
     12 #include "base/scoped_ptr.h"
     13 #include "net/proxy/proxy_resolver.h"
     14 
     15 namespace base {
     16 class Thread;
     17 }  // namespace base
     18 
     19 namespace net {
     20 
     21 // ProxyResolver implementation that wraps a synchronous ProxyResolver, and
     22 // runs it on a single worker thread. If multiple requests accumulate, they
     23 // are serviced in FIFO order.
     24 class SingleThreadedProxyResolver : public ProxyResolver {
     25  public:
     26   // |resolver| is a synchronous ProxyResolver implementation. It doesn't
     27   // have to be thread-safe, since it is run on exactly one thread. The
     28   // constructor takes ownership of |resolver|.
     29   explicit SingleThreadedProxyResolver(ProxyResolver* resolver);
     30 
     31   virtual ~SingleThreadedProxyResolver();
     32 
     33   // ProxyResolver implementation:
     34   virtual int GetProxyForURL(const GURL& url,
     35                              ProxyInfo* results,
     36                              CompletionCallback* callback,
     37                              RequestHandle* request,
     38                              LoadLog* load_log);
     39   virtual void CancelRequest(RequestHandle request);
     40   virtual void CancelSetPacScript();
     41   virtual void PurgeMemory();
     42 
     43  protected:
     44   // The wrapped (synchronous) ProxyResolver.
     45   ProxyResolver* resolver() { return resolver_.get(); }
     46 
     47  private:
     48   // Refcounted helper class that bridges between origin thread and worker
     49   // thread.
     50   class Job;
     51   friend class Job;
     52   class SetPacScriptTask;
     53   friend class SetPacScriptTask;
     54   // FIFO queue that contains the in-progress job, and any pending jobs.
     55   typedef std::deque<scoped_refptr<Job> > PendingJobsQueue;
     56 
     57   base::Thread* thread() { return thread_.get(); }
     58 
     59   // ProxyResolver implementation:
     60   virtual int SetPacScript(const GURL& pac_url,
     61                            const std::string& pac_bytes,
     62                            CompletionCallback* callback);
     63 
     64   // Starts the worker thread if it isn't already running.
     65   void EnsureThreadStarted();
     66 
     67   // Starts the next job from |pending_jobs_| if possible.
     68   void ProcessPendingJobs();
     69 
     70   // Removes the front entry of the jobs queue. |expected_job| is our
     71   // expectation of what the front of the job queue is; it is only used by
     72   // DCHECK for verification purposes.
     73   void RemoveFrontOfJobsQueueAndStartNext(Job* expected_job);
     74 
     75   // Clears |outstanding_set_pac_script_task_|.
     76   // Called when |task| has just finished.
     77   void RemoveOutstandingSetPacScriptTask(SetPacScriptTask* task);
     78 
     79   // The synchronous resolver implementation.
     80   scoped_ptr<ProxyResolver> resolver_;
     81 
     82   // The thread where |resolver_| is run on.
     83   // Note that declaration ordering is important here. |thread_| needs to be
     84   // destroyed *before* |resolver_|, in case |resolver_| is currently
     85   // executing on |thread_|.
     86   scoped_ptr<base::Thread> thread_;
     87 
     88   PendingJobsQueue pending_jobs_;
     89   scoped_refptr<SetPacScriptTask> outstanding_set_pac_script_task_;
     90 };
     91 
     92 }  // namespace net
     93 
     94 #endif  // NET_PROXY_SINGLE_THREADED_PROXY_RESOLVER_H_
     95