1// Copyright (c) 2011 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_PROXY_RESOLVER_V8_H_
6#define NET_PROXY_PROXY_RESOLVER_V8_H_
7
8#include "base/compiler_specific.h"
9#include "base/memory/scoped_ptr.h"
10#include "net/base/net_export.h"
11#include "net/proxy/proxy_resolver.h"
12
13namespace gin {
14class IsolateHolder;
15}  // namespace gin
16
17namespace v8 {
18class HeapStatistics;
19class Isolate;
20}  // namespace v8
21
22namespace net {
23
24// Implementation of ProxyResolver that uses V8 to evaluate PAC scripts.
25//
26// ----------------------------------------------------------------------------
27// !!! Important note on threading model:
28// ----------------------------------------------------------------------------
29// There can be only one instance of V8 running at a time. To enforce this
30// constraint, ProxyResolverV8 holds a v8::Locker during execution. Therefore
31// it is OK to run multiple instances of ProxyResolverV8 on different threads,
32// since only one will be running inside V8 at a time.
33//
34// It is important that *ALL* instances of V8 in the process be using
35// v8::Locker. If not there can be race conditions between the non-locked V8
36// instances and the locked V8 instances used by ProxyResolverV8 (assuming they
37// run on different threads).
38//
39// This is the case with the V8 instance used by chromium's renderer -- it runs
40// on a different thread from ProxyResolver (renderer thread vs PAC thread),
41// and does not use locking since it expects to be alone.
42class NET_EXPORT_PRIVATE ProxyResolverV8 : public ProxyResolver {
43 public:
44  // Interface for the javascript bindings.
45  class NET_EXPORT_PRIVATE JSBindings {
46   public:
47    enum ResolveDnsOperation {
48      DNS_RESOLVE,
49      DNS_RESOLVE_EX,
50      MY_IP_ADDRESS,
51      MY_IP_ADDRESS_EX,
52    };
53
54    JSBindings() {}
55
56    // Handler for "dnsResolve()", "dnsResolveEx()", "myIpAddress()",
57    // "myIpAddressEx()". Returns true on success and fills |*output| with the
58    // result. If |*terminate| is set to true, then the script execution will
59    // be aborted. Note that termination may not happen right away.
60    virtual bool ResolveDns(const std::string& host,
61                            ResolveDnsOperation op,
62                            std::string* output,
63                            bool* terminate) = 0;
64
65    // Handler for "alert(message)"
66    virtual void Alert(const base::string16& message) = 0;
67
68    // Handler for when an error is encountered. |line_number| may be -1
69    // if a line number is not applicable to this error.
70    virtual void OnError(int line_number, const base::string16& error) = 0;
71
72   protected:
73    virtual ~JSBindings() {}
74  };
75
76  // Constructs a ProxyResolverV8.
77  ProxyResolverV8();
78
79  virtual ~ProxyResolverV8();
80
81  JSBindings* js_bindings() const { return js_bindings_; }
82  void set_js_bindings(JSBindings* js_bindings) { js_bindings_ = js_bindings; }
83
84  // ProxyResolver implementation:
85  virtual int GetProxyForURL(const GURL& url,
86                             ProxyInfo* results,
87                             const net::CompletionCallback& /*callback*/,
88                             RequestHandle* /*request*/,
89                             const BoundNetLog& net_log) OVERRIDE;
90  virtual void CancelRequest(RequestHandle request) OVERRIDE;
91  virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE;
92  virtual void CancelSetPacScript() OVERRIDE;
93  virtual int SetPacScript(
94      const scoped_refptr<ProxyResolverScriptData>& script_data,
95      const net::CompletionCallback& /*callback*/) OVERRIDE;
96
97  // Create an isolate to use for the proxy resolver. If the embedder invokes
98  // this method multiple times, it must be invoked in a thread safe manner,
99  // e.g. always from the same thread.
100  static void EnsureIsolateCreated();
101
102  static v8::Isolate* GetDefaultIsolate();
103
104  // Get total/ued heap memory usage of all v8 instances used by the proxy
105  // resolver.
106  static size_t GetTotalHeapSize();
107  static size_t GetUsedHeapSize();
108
109 private:
110  static gin::IsolateHolder* g_proxy_resolver_isolate_;
111
112  // Context holds the Javascript state for the most recently loaded PAC
113  // script. It corresponds with the data from the last call to
114  // SetPacScript().
115  class Context;
116
117  scoped_ptr<Context> context_;
118
119  JSBindings* js_bindings_;
120
121  DISALLOW_COPY_AND_ASSIGN(ProxyResolverV8);
122};
123
124}  // namespace net
125
126#endif  // NET_PROXY_PROXY_RESOLVER_V8_H_
127