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