| OLD | NEW |
| (Empty) |
| 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_MULTI_THREADED_PROXY_RESOLVER_H_ | |
| 6 #define NET_PROXY_MULTI_THREADED_PROXY_RESOLVER_H_ | |
| 7 | |
| 8 #include <deque> | |
| 9 #include <string> | |
| 10 #include <vector> | |
| 11 | |
| 12 #include "base/basictypes.h" | |
| 13 #include "base/non_thread_safe.h" | |
| 14 #include "base/ref_counted.h" | |
| 15 #include "base/scoped_ptr.h" | |
| 16 #include "net/proxy/proxy_resolver.h" | |
| 17 | |
| 18 namespace base { | |
| 19 class Thread; | |
| 20 } // namespace base | |
| 21 | |
| 22 namespace net { | |
| 23 | |
| 24 // ProxyResolverFactory is an interface for creating ProxyResolver instances. | |
| 25 class ProxyResolverFactory { | |
| 26 public: | |
| 27 explicit ProxyResolverFactory(bool resolvers_expect_pac_bytes) | |
| 28 : resolvers_expect_pac_bytes_(resolvers_expect_pac_bytes) {} | |
| 29 | |
| 30 virtual ~ProxyResolverFactory() {} | |
| 31 | |
| 32 // Creates a new ProxyResolver. The caller is responsible for freeing this | |
| 33 // object. | |
| 34 virtual ProxyResolver* CreateProxyResolver() = 0; | |
| 35 | |
| 36 bool resolvers_expect_pac_bytes() const { | |
| 37 return resolvers_expect_pac_bytes_; | |
| 38 } | |
| 39 | |
| 40 private: | |
| 41 bool resolvers_expect_pac_bytes_; | |
| 42 DISALLOW_COPY_AND_ASSIGN(ProxyResolverFactory); | |
| 43 }; | |
| 44 | |
| 45 // MultiThreadedProxyResolver is a ProxyResolver implementation that runs | |
| 46 // synchronous ProxyResolver implementations on worker threads. | |
| 47 // | |
| 48 // Threads are created lazily on demand, up to a maximum total. The advantage | |
| 49 // of having a pool of threads, is faster performance. In particular, being | |
| 50 // able to keep servicing PAC requests even if one blocks its execution. | |
| 51 // | |
| 52 // During initialization (SetPacScript), a single thread is spun up to test | |
| 53 // the script. If this succeeds, we cache the input script, and will re-use | |
| 54 // this to lazily provision any new threads as needed. | |
| 55 // | |
| 56 // For each new thread that we spawn, a corresponding new ProxyResolver is | |
| 57 // created using ProxyResolverFactory. | |
| 58 // | |
| 59 // Because we are creating multiple ProxyResolver instances, this means we | |
| 60 // are duplicating script contexts for what is ordinarily seen as being a | |
| 61 // single script. This can affect compatibility on some classes of PAC | |
| 62 // script: | |
| 63 // | |
| 64 // (a) Scripts whose initialization has external dependencies on network or | |
| 65 // time may end up successfully initializing on some threads, but not | |
| 66 // others. So depending on what thread services the request, the result | |
| 67 // may jump between several possibilities. | |
| 68 // | |
| 69 // (b) Scripts whose FindProxyForURL() depends on side-effects may now | |
| 70 // work differently. For example, a PAC script which was incrementing | |
| 71 // a global counter and using that to make a decision. In the | |
| 72 // multi-threaded model, each thread may have a different value for this | |
| 73 // counter, so it won't globally be seen as monotonically increasing! | |
| 74 class MultiThreadedProxyResolver : public ProxyResolver, public NonThreadSafe { | |
| 75 public: | |
| 76 // Creates an asynchronous ProxyResolver that runs requests on up to | |
| 77 // |max_num_threads|. | |
| 78 // | |
| 79 // For each thread that is created, an accompanying synchronous ProxyResolver | |
| 80 // will be provisioned using |resolver_factory|. All methods on these | |
| 81 // ProxyResolvers will be called on the one thread, with the exception of | |
| 82 // ProxyResolver::Shutdown() which will be called from the origin thread | |
| 83 // prior to destruction. | |
| 84 // | |
| 85 // The constructor takes ownership of |resolver_factory|. | |
| 86 MultiThreadedProxyResolver(ProxyResolverFactory* resolver_factory, | |
| 87 size_t max_num_threads); | |
| 88 | |
| 89 virtual ~MultiThreadedProxyResolver(); | |
| 90 | |
| 91 // ProxyResolver implementation: | |
| 92 virtual int GetProxyForURL(const GURL& url, | |
| 93 ProxyInfo* results, | |
| 94 CompletionCallback* callback, | |
| 95 RequestHandle* request, | |
| 96 const BoundNetLog& net_log); | |
| 97 virtual void CancelRequest(RequestHandle request); | |
| 98 virtual void CancelSetPacScript(); | |
| 99 virtual void PurgeMemory(); | |
| 100 | |
| 101 private: | |
| 102 class Executor; | |
| 103 class Job; | |
| 104 class SetPacScriptJob; | |
| 105 class GetProxyForURLJob; | |
| 106 // FIFO queue of pending jobs waiting to be started. | |
| 107 // TODO(eroman): Make this priority queue. | |
| 108 typedef std::deque<scoped_refptr<Job> > PendingJobsQueue; | |
| 109 typedef std::vector<scoped_refptr<Executor> > ExecutorList; | |
| 110 | |
| 111 // ProxyResolver implementation: | |
| 112 virtual int SetPacScript(const GURL& pac_url, | |
| 113 const string16& pac_script, | |
| 114 CompletionCallback* callback); | |
| 115 | |
| 116 // Asserts that there are no outstanding user-initiated jobs on any of the | |
| 117 // worker threads. | |
| 118 void CheckNoOutstandingUserRequests() const; | |
| 119 | |
| 120 // Stops and deletes all of the worker threads. | |
| 121 void ReleaseAllExecutors(); | |
| 122 | |
| 123 // Returns an idle worker thread which is ready to receive GetProxyForURL() | |
| 124 // requests. If all threads are occupied, returns NULL. | |
| 125 Executor* FindIdleExecutor(); | |
| 126 | |
| 127 // Creates a new worker thread, and appends it to |executors_|. | |
| 128 Executor* AddNewExecutor(); | |
| 129 | |
| 130 // Starts the next job from |pending_jobs_| if possible. | |
| 131 void OnExecutorReady(Executor* executor); | |
| 132 | |
| 133 const scoped_ptr<ProxyResolverFactory> resolver_factory_; | |
| 134 const size_t max_num_threads_; | |
| 135 PendingJobsQueue pending_jobs_; | |
| 136 ExecutorList executors_; | |
| 137 bool was_set_pac_script_called_; | |
| 138 GURL current_pac_url_; | |
| 139 string16 current_pac_script_; | |
| 140 }; | |
| 141 | |
| 142 } // namespace net | |
| 143 | |
| 144 #endif // NET_PROXY_MULTI_THREADED_PROXY_RESOLVER_H_ | |
| OLD | NEW |