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