// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef NET_PROXY_MULTI_THREADED_PROXY_RESOLVER_H_ #define NET_PROXY_MULTI_THREADED_PROXY_RESOLVER_H_ #include #include #include #include "base/memory/ref_counted.h" #include "net/base/net_export.h" #include "net/proxy/proxy_resolver_factory.h" namespace net { class ProxyResolver; // MultiThreadedProxyResolverFactory creates instances of a ProxyResolver // implementation that runs synchronous ProxyResolver implementations on worker // threads. // // Threads are created lazily on demand, up to a maximum total. The advantage // of having a pool of threads, is faster performance. In particular, being // able to keep servicing PAC requests even if one blocks its execution. // // During initialization (CreateProxyResolver), a single thread is spun up to // test the script. If this succeeds, we cache the input script, and will re-use // this to lazily provision any new threads as needed. // // For each new thread that we spawn in a particular MultiThreadedProxyResolver // instance, a corresponding new ProxyResolver is created using the // ProxyResolverFactory returned by CreateProxyResolverFactory(). // // Because we are creating multiple ProxyResolver instances, this means we // are duplicating script contexts for what is ordinarily seen as being a // single script. This can affect compatibility on some classes of PAC // script: // // (a) Scripts whose initialization has external dependencies on network or // time may end up successfully initializing on some threads, but not // others. So depending on what thread services the request, the result // may jump between several possibilities. // // (b) Scripts whose FindProxyForURL() depends on side-effects may now // work differently. For example, a PAC script which was incrementing // a global counter and using that to make a decision. In the // multi-threaded model, each thread may have a different value for this // counter, so it won't globally be seen as monotonically increasing! class NET_EXPORT_PRIVATE MultiThreadedProxyResolverFactory : public ProxyResolverFactory { public: MultiThreadedProxyResolverFactory(size_t max_num_threads, bool factory_expects_bytes); ~MultiThreadedProxyResolverFactory() override; int CreateProxyResolver( const scoped_refptr& pac_script, std::unique_ptr* resolver, const CompletionCallback& callback, std::unique_ptr* request) override; private: class Job; // Invoked to create a ProxyResolverFactory instance to pass to a // MultiThreadedProxyResolver instance. virtual std::unique_ptr CreateProxyResolverFactory() = 0; void RemoveJob(Job* job); const size_t max_num_threads_; std::set jobs_; }; } // namespace net #endif // NET_PROXY_MULTI_THREADED_PROXY_RESOLVER_H_