summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/net/chrome_url_request_context.cc17
-rw-r--r--chrome/browser/net/connection_tester.cc2
-rw-r--r--chrome/common/chrome_switches.cc4
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--chrome/service/net/service_url_request_context.cc3
-rw-r--r--net/proxy/proxy_service.cc12
-rw-r--r--net/proxy/proxy_service.h17
-rw-r--r--webkit/tools/test_shell/test_shell_request_context.cc2
8 files changed, 51 insertions, 7 deletions
diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc
index 712fbf7..27fc4d7 100644
--- a/chrome/browser/net/chrome_url_request_context.cc
+++ b/chrome/browser/net/chrome_url_request_context.cc
@@ -96,9 +96,26 @@ net::ProxyService* CreateProxyService(
use_v8 = false; // Fallback to non-v8 implementation.
}
+ size_t num_pac_threads = 0u; // Use default number of threads.
+
+ // Check the command line for an override on the number of proxy resolver
+ // threads to use.
+ if (command_line.HasSwitch(switches::kNumPacThreads)) {
+ std::string s = command_line.GetSwitchValueASCII(switches::kNumPacThreads);
+
+ // Parse the switch (it should be a positive integer formatted as decimal).
+ int n;
+ if (StringToInt(s, &n) && n > 0) {
+ num_pac_threads = static_cast<size_t>(n);
+ } else {
+ LOG(ERROR) << "Invalid switch for number of PAC threads: " << s;
+ }
+ }
+
return net::ProxyService::Create(
proxy_config_service,
use_v8,
+ num_pac_threads,
context,
net_log,
io_loop);
diff --git a/chrome/browser/net/connection_tester.cc b/chrome/browser/net/connection_tester.cc
index 26c2d1d..162be2c 100644
--- a/chrome/browser/net/connection_tester.cc
+++ b/chrome/browser/net/connection_tester.cc
@@ -151,7 +151,7 @@ class ExperimentURLRequestContext : public URLRequestContext {
}
*proxy_service = net::ProxyService::Create(config_service.release(), true,
- this, NULL, MessageLoop::current());
+ 0u, this, NULL, MessageLoop::current());
return net::OK;
}
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 365016b..6140243 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -632,6 +632,10 @@ const char kNoProxyServer[] = "no-proxy-server";
// Runs the renderer outside the sandbox.
const char kNoSandbox[] = "no-sandbox";
+// Specifies the maximum number of threads to use for running the Proxy
+// Autoconfig (PAC) script.
+const char kNumPacThreads[] = "num-pac-threads";
+
// Launch URL in new browser window.
const char kOpenInNewWindow[] = "new-window";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 71367dd..97eb92d 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -188,6 +188,7 @@ extern const char kNoJsRandomness[];
extern const char kNoProxyServer[];
extern const char kNoReferrers[];
extern const char kNoSandbox[];
+extern const char kNumPacThreads[];
extern const char kOpenInNewWindow[];
extern const char kPackExtension[];
extern const char kPackExtensionKey[];
diff --git a/chrome/service/net/service_url_request_context.cc b/chrome/service/net/service_url_request_context.cc
index ee416fe..d33538b 100644
--- a/chrome/service/net/service_url_request_context.cc
+++ b/chrome/service/net/service_url_request_context.cc
@@ -31,7 +31,8 @@ ServiceURLRequestContext::ServiceURLRequestContext() {
g_service_process->io_thread()->message_loop(),
g_service_process->file_thread()->message_loop());
proxy_service_ =
- net::ProxyService::Create(proxy_config_service, false, this, NULL, NULL);
+ net::ProxyService::Create(
+ proxy_config_service, false, 0u, this, NULL, NULL);
ftp_transaction_factory_ = new net::FtpNetworkLayer(host_resolver_);
ssl_config_service_ = new net::SSLConfigServiceDefaults;
http_auth_handler_factory_ = net::HttpAuthHandlerFactory::CreateDefault();
diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc
index 060745b..e6dc15e 100644
--- a/net/proxy/proxy_service.cc
+++ b/net/proxy/proxy_service.cc
@@ -39,6 +39,7 @@ using base::TimeTicks;
namespace net {
static const size_t kMaxNumNetLogEntries = 100;
+static const size_t kDefaultNumPacThreads = 4;
// Config getter that fails every time.
class ProxyConfigServiceNull : public ProxyConfigService {
@@ -264,9 +265,12 @@ ProxyService::ProxyService(ProxyConfigService* config_service,
ProxyService* ProxyService::Create(
ProxyConfigService* proxy_config_service,
bool use_v8_resolver,
+ size_t num_pac_threads,
URLRequestContext* url_request_context,
NetLog* net_log,
MessageLoop* io_loop) {
+ if (num_pac_threads == 0)
+ num_pac_threads = kDefaultNumPacThreads;
ProxyResolverFactory* sync_resolver_factory;
if (use_v8_resolver) {
@@ -278,10 +282,8 @@ ProxyService* ProxyService::Create(
sync_resolver_factory = new ProxyResolverFactoryForNonV8();
}
- const size_t kMaxNumResolverThreads = 1u;
ProxyResolver* proxy_resolver =
- new MultiThreadedProxyResolver(sync_resolver_factory,
- kMaxNumResolverThreads);
+ new MultiThreadedProxyResolver(sync_resolver_factory, num_pac_threads);
ProxyService* proxy_service =
new ProxyService(proxy_config_service, proxy_resolver, net_log);
@@ -298,7 +300,9 @@ ProxyService* ProxyService::Create(
// static
ProxyService* ProxyService::CreateFixed(const ProxyConfig& pc) {
- return Create(new ProxyConfigServiceFixed(pc), false, NULL, NULL, NULL);
+ // TODO(eroman): This isn't quite right, won't work if |pc| specifies
+ // a PAC script.
+ return Create(new ProxyConfigServiceFixed(pc), false, 0, NULL, NULL, NULL);
}
// static
diff --git a/net/proxy/proxy_service.h b/net/proxy/proxy_service.h
index 5c981f8..a702b38 100644
--- a/net/proxy/proxy_service.h
+++ b/net/proxy/proxy_service.h
@@ -137,6 +137,22 @@ class ProxyService : public base::RefCountedThreadSafe<ProxyService>,
// the proxy settings change. We take ownership of |proxy_config_service|.
// Iff |use_v8_resolver| is true, then the V8 implementation is
// used.
+ //
+ // |num_pac_threads| specifies the maximum number of threads to use for
+ // executing PAC scripts. Threads are created lazily on demand.
+ // If |0| is specified, then a default number of threads will be selected.
+ //
+ // Having more threads avoids stalling proxy resolve requests when the
+ // PAC script takes a while to run. This is particularly a problem when PAC
+ // scripts do synchronous DNS resolutions, since that can take on the order
+ // of seconds.
+ //
+ // However, the disadvantages of using more than 1 thread are:
+ // (a) can cause compatibility issues for scripts that rely on side effects
+ // between runs (such scripts should not be common though).
+ // (b) increases the memory used by proxy resolving, as each thread will
+ // duplicate its own script context.
+
// |url_request_context| is only used when use_v8_resolver is true:
// it specifies the URL request context that will be used if a PAC
// script needs to be fetched.
@@ -150,6 +166,7 @@ class ProxyService : public base::RefCountedThreadSafe<ProxyService>,
static ProxyService* Create(
ProxyConfigService* proxy_config_service,
bool use_v8_resolver,
+ size_t num_pac_threads,
URLRequestContext* url_request_context,
NetLog* net_log,
MessageLoop* io_loop);
diff --git a/webkit/tools/test_shell/test_shell_request_context.cc b/webkit/tools/test_shell/test_shell_request_context.cc
index a39e259..1d9a6030 100644
--- a/webkit/tools/test_shell/test_shell_request_context.cc
+++ b/webkit/tools/test_shell/test_shell_request_context.cc
@@ -59,7 +59,7 @@ void TestShellRequestContext::Init(
#endif
host_resolver_ = net::CreateSystemHostResolver();
proxy_service_ = net::ProxyService::Create(proxy_config_service.release(),
- false, NULL, NULL, NULL);
+ false, 0, NULL, NULL, NULL);
ssl_config_service_ = net::SSLConfigService::CreateSystemSSLConfigService();
http_auth_handler_factory_ = net::HttpAuthHandlerFactory::CreateDefault();