// 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_RESOLUTION_MULTI_THREADED_PROXY_RESOLVER_H_
#define NET_PROXY_RESOLUTION_MULTI_THREADED_PROXY_RESOLVER_H_

#include <stddef.h>

#include <memory>
#include <set>

#include "base/memory/ref_counted.h"
#include "net/base/completion_once_callback.h"
#include "net/base/net_export.h"
#include "net/proxy_resolution/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<PacFileData>& pac_script,
                          std::unique_ptr<ProxyResolver>* resolver,
                          CompletionOnceCallback callback,
                          std::unique_ptr<Request>* request) override;

 private:
  class Job;

  // Invoked to create a ProxyResolverFactory instance to pass to a
  // MultiThreadedProxyResolver instance.
  virtual std::unique_ptr<ProxyResolverFactory>
  CreateProxyResolverFactory() = 0;

  void RemoveJob(Job* job);

  const size_t max_num_threads_;

  std::set<Job*> jobs_;
};

}  // namespace net

#endif  // NET_PROXY_RESOLUTION_MULTI_THREADED_PROXY_RESOLVER_H_
