• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 The Chromium Authors
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_RESOLUTION_MULTI_THREADED_PROXY_RESOLVER_H_
6 #define NET_PROXY_RESOLUTION_MULTI_THREADED_PROXY_RESOLVER_H_
7 
8 #include <stddef.h>
9 
10 #include <memory>
11 #include <set>
12 
13 #include "base/memory/scoped_refptr.h"
14 #include "net/base/completion_once_callback.h"
15 #include "net/base/net_export.h"
16 #include "net/proxy_resolution/proxy_resolver_factory.h"
17 
18 namespace net {
19 class ProxyResolver;
20 
21 // MultiThreadedProxyResolverFactory creates instances of a ProxyResolver
22 // implementation that runs synchronous ProxyResolver implementations on worker
23 // threads.
24 //
25 // Threads are created lazily on demand, up to a maximum total. The advantage
26 // of having a pool of threads, is faster performance. In particular, being
27 // able to keep servicing PAC requests even if one blocks its execution.
28 //
29 // During initialization (CreateProxyResolver), a single thread is spun up to
30 // test the script. If this succeeds, we cache the input script, and will re-use
31 // this to lazily provision any new threads as needed.
32 //
33 // For each new thread that we spawn in a particular MultiThreadedProxyResolver
34 // instance, a corresponding new ProxyResolver is created using the
35 // ProxyResolverFactory returned by CreateProxyResolverFactory().
36 //
37 // Because we are creating multiple ProxyResolver instances, this means we
38 // are duplicating script contexts for what is ordinarily seen as being a
39 // single script. This can affect compatibility on some classes of PAC
40 // script:
41 //
42 // (a) Scripts whose initialization has external dependencies on network or
43 //     time may end up successfully initializing on some threads, but not
44 //     others. So depending on what thread services the request, the result
45 //     may jump between several possibilities.
46 //
47 // (b) Scripts whose FindProxyForURL() depends on side-effects may now
48 //     work differently. For example, a PAC script which was incrementing
49 //     a global counter and using that to make a decision. In the
50 //     multi-threaded model, each thread may have a different value for this
51 //     counter, so it won't globally be seen as monotonically increasing!
52 class NET_EXPORT_PRIVATE MultiThreadedProxyResolverFactory
53     : public ProxyResolverFactory {
54  public:
55   MultiThreadedProxyResolverFactory(size_t max_num_threads,
56                                     bool factory_expects_bytes);
57   ~MultiThreadedProxyResolverFactory() override;
58 
59   int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
60                           std::unique_ptr<ProxyResolver>* resolver,
61                           CompletionOnceCallback callback,
62                           std::unique_ptr<Request>* request) override;
63 
64  private:
65   class Job;
66 
67   // Invoked to create a ProxyResolverFactory instance to pass to a
68   // MultiThreadedProxyResolver instance.
69   virtual std::unique_ptr<ProxyResolverFactory>
70   CreateProxyResolverFactory() = 0;
71 
72   void RemoveJob(Job* job);
73 
74   const size_t max_num_threads_;
75 
76   std::set<Job*> jobs_;
77 };
78 
79 }  // namespace net
80 
81 #endif  // NET_PROXY_RESOLUTION_MULTI_THREADED_PROXY_RESOLVER_H_
82