12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/proxy/proxy_resolver_v8_tracing.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 95e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/synchronization/cancellation_flag.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/synchronization/waitable_event.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread_restrictions.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/address_list.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_errors.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_log.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/host_resolver.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/proxy/proxy_info.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/proxy/proxy_resolver_error_observer.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/proxy/proxy_resolver_v8.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The intent of this class is explained in the design document: 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// https://docs.google.com/a/chromium.org/document/d/16Ij5OcVnR3s0MH4Z5XkhI9VTPoMJdaBn9rKreAmGOdE/edit 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// In a nutshell, PAC scripts are Javascript programs and may depend on 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// network I/O, by calling functions like dnsResolve(). 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This is problematic since functions such as dnsResolve() will block the 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Javascript execution until the DNS result is availble, thereby stalling the 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// PAC thread, which hurts the ability to process parallel proxy resolves. 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// An obvious solution is to simply start more PAC threads, however this scales 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// poorly, which hurts the ability to process parallel proxy resolves. 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The solution in ProxyResolverV8Tracing is to model PAC scripts as being 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// deterministic, and depending only on the inputted URL. When the script 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// issues a dnsResolve() for a yet unresolved hostname, the Javascript 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// execution is "aborted", and then re-started once the DNS result is 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// known. 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net { 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Upper bound on how many *unique* DNS resolves a PAC script is allowed 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// to make. This is a failsafe both for scripts that do a ridiculous 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// number of DNS resolves, as well as scripts which are misbehaving 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// under the tracing optimization. It is not expected to hit this normally. 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const size_t kMaxUniqueResolveDnsPerExec = 20; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Approximate number of bytes to use for buffering alerts() and errors. 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This is a failsafe in case repeated executions of the script causes 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// too much memory bloat. It is not expected for well behaved scripts to 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// hit this. (In fact normal scripts should not even have alerts() or errors). 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const size_t kMaxAlertsAndErrorsBytes = 2048; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns event parameters for a PAC error message (line number + message). 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::Value* NetLogErrorCallback(int line_number, 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::string16* message, 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NetLog::LogLevel /* log_level */) { 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict->SetInteger("line_number", line_number); 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict->SetString("message", *message); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dict; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The Job class is responsible for executing GetProxyForURL() and 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// SetPacScript(), since both of these operations share similar code. 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The DNS for these operations can operate in either blocking or 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// non-blocking mode. Blocking mode is used as a fallback when the PAC script 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// seems to be misbehaving under the tracing optimization. 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Note that this class runs on both the origin thread and a worker 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// thread. Most methods are expected to be used exclusively on one thread 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// or the other. 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The lifetime of Jobs does not exceed that of the ProxyResolverV8Tracing that 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// spawned it. Destruction might happen on either the origin thread or the 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// worker thread. 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ProxyResolverV8Tracing::Job 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public base::RefCountedThreadSafe<ProxyResolverV8Tracing::Job>, 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public ProxyResolverV8::JSBindings { 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |parent| is non-owned. It is the ProxyResolverV8Tracing that spawned this 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Job, and must oulive it. 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit Job(ProxyResolverV8Tracing* parent); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Called from origin thread. 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void StartSetPacScript( 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const scoped_refptr<ProxyResolverScriptData>& script_data, 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CompletionCallback& callback); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Called from origin thread. 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void StartGetProxyForURL(const GURL& url, 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyInfo* results, 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BoundNetLog& net_log, 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CompletionCallback& callback); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Called from origin thread. 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Cancel(); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Called from origin thread. 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LoadState GetLoadState() const; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef std::map<std::string, std::string> DnsCache; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class base::RefCountedThreadSafe<ProxyResolverV8Tracing::Job>; 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enum Operation { 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SET_PAC_SCRIPT, 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GET_PROXY_FOR_URL, 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct AlertOrError { 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_alert; 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int line_number; 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16 message; 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~Job(); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void CheckIsOnWorkerThread() const; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void CheckIsOnOriginThread() const; 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetCallback(const CompletionCallback& callback); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ReleaseCallback(); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyResolverV8* v8_resolver(); 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop* worker_loop(); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HostResolver* host_resolver(); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyResolverErrorObserver* error_observer(); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NetLog* net_log(); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Invokes the user's callback. 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void NotifyCaller(int result); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void NotifyCallerOnOriginLoop(int result); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Start(Operation op, bool blocking_dns, 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CompletionCallback& callback); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ExecuteBlocking(); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ExecuteNonBlocking(); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int ExecuteProxyResolver(); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Implementation of ProxyResolverv8::JSBindings 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool ResolveDns(const std::string& host, 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResolveDnsOperation op, 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* output, 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* terminate) OVERRIDE; 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void Alert(const base::string16& message) OVERRIDE; 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnError(int line_number, const base::string16& error) OVERRIDE; 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ResolveDnsBlocking(const std::string& host, 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResolveDnsOperation op, 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* output); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ResolveDnsNonBlocking(const std::string& host, 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResolveDnsOperation op, 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* output, 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* terminate); 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool PostDnsOperationAndWait(const std::string& host, 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResolveDnsOperation op, 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* completed_synchronously) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WARN_UNUSED_RESULT; 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void DoDnsOperation(); 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void OnDnsOperationComplete(int result); 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ScheduleRestartWithBlockingDns(); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool GetDnsFromLocalCache(const std::string& host, ResolveDnsOperation op, 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* output, bool* return_value); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SaveDnsToLocalCache(const std::string& host, ResolveDnsOperation op, 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int net_error, const net::AddressList& addresses); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Builds a RequestInfo to service the specified PAC DNS operation. 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static HostResolver::RequestInfo MakeDnsRequestInfo(const std::string& host, 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResolveDnsOperation op); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Makes a key for looking up |host, op| in |dns_cache_|. Strings are used for 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // convenience, to avoid defining custom comparators. 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static std::string MakeDnsCacheKey(const std::string& host, 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResolveDnsOperation op); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void HandleAlertOrError(bool is_alert, int line_number, 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::string16& message); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void DispatchBufferedAlertsAndErrors(); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void DispatchAlertOrError(bool is_alert, int line_number, 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::string16& message); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void LogEventToCurrentRequestAndGlobally( 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NetLog::EventType type, 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const NetLog::ParametersCallback& parameters_callback); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The thread which called into ProxyResolverV8Tracing, and on which the 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // completion callback is expected to run. 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::MessageLoopProxy> origin_loop_; 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The ProxyResolverV8Tracing which spawned this Job. 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Initialized on origin thread and then accessed from both threads. 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyResolverV8Tracing* parent_; 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The callback to run (on the origin thread) when the Job finishes. 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Should only be accessed from origin thread. 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CompletionCallback callback_; 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Flag to indicate whether the request has been cancelled. 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::CancellationFlag cancelled_; 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The operation that this Job is running. 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Initialized on origin thread and then accessed from both threads. 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Operation operation_; 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The DNS mode for this Job. 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Initialized on origin thread, mutated on worker thread, and accessed 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // by both the origin thread and worker thread. 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool blocking_dns_; 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Used to block the worker thread on a DNS operation taking place on the 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // origin thread. 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WaitableEvent event_; 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Map of DNS operations completed so far. Written into on the origin thread 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // and read on the worker thread. 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DnsCache dns_cache_; 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The job holds a reference to itself to ensure that it remains alive until 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // either completion or cancellation. 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<Job> owned_self_reference_; 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ------------------------------------------------------- 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // State specific to SET_PAC_SCRIPT. 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ------------------------------------------------------- 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<ProxyResolverScriptData> script_data_; 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ------------------------------------------------------- 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // State specific to GET_PROXY_FOR_URL. 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ------------------------------------------------------- 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyInfo* user_results_; // Owned by caller, lives on origin thread. 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url_; 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyInfo results_; 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BoundNetLog bound_net_log_; 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // --------------------------------------------------------------------------- 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // State for ExecuteNonBlocking() 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // --------------------------------------------------------------------------- 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // These variables are used exclusively on the worker thread and are only 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // meaningful when executing inside of ExecuteNonBlocking(). 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Whether this execution was abandoned due to a missing DNS dependency. 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool abandoned_; 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Number of calls made to ResolveDns() by this execution. 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_dns_; 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sequence of calls made to Alert() or OnError() by this execution. 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<AlertOrError> alerts_and_errors_; 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t alerts_and_errors_byte_cost_; // Approximate byte cost of the above. 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Number of calls made to ResolveDns() by the PREVIOUS execution. 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int last_num_dns_; 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Whether the current execution needs to be restarted in blocking mode. 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool should_restart_with_blocking_dns_; 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // --------------------------------------------------------------------------- 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // State for pending DNS request. 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // --------------------------------------------------------------------------- 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Handle to the outstanding request in the HostResolver, or NULL. 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is mutated and used on the origin thread, however it may be read by 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the worker thread for some DCHECKS(). 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HostResolver::RequestHandle pending_dns_; 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Indicates if the outstanding DNS request completed synchronously. Written 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // on the origin thread, and read by the worker thread. 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool pending_dns_completed_synchronously_; 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // These are the inputs to DoDnsOperation(). Written on the worker thread, 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // read by the origin thread. 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string pending_dns_host_; 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResolveDnsOperation pending_dns_op_; 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This contains the resolved address list that DoDnsOperation() fills in. 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Used exclusively on the origin thread. 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddressList pending_dns_addresses_; 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProxyResolverV8Tracing::Job::Job(ProxyResolverV8Tracing* parent) 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : origin_loop_(base::MessageLoopProxy::current()), 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parent_(parent), 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_(true, false), 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_num_dns_(0), 3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pending_dns_(NULL) { 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnOriginThread(); 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::StartSetPacScript( 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const scoped_refptr<ProxyResolverScriptData>& script_data, 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CompletionCallback& callback) { 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnOriginThread(); 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) script_data_ = script_data; 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Script initialization uses blocking DNS since there isn't any 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // advantage to using non-blocking mode here. That is because the 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // parent ProxyService can't submit any ProxyResolve requests until 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // initialization has completed successfully! 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Start(SET_PAC_SCRIPT, true /*blocking*/, callback); 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::StartGetProxyForURL( 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& url, 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyInfo* results, 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BoundNetLog& net_log, 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CompletionCallback& callback) { 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnOriginThread(); 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url_ = url; 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) user_results_ = results; 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound_net_log_ = net_log; 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Start(GET_PROXY_FOR_URL, false /*non-blocking*/, callback); 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::Cancel() { 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnOriginThread(); 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // There are several possibilities to consider for cancellation: 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (a) The job has been posted to the worker thread, however script execution 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // has not yet started. 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (b) The script is executing on the worker thread. 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (c) The script is executing on the worker thread, however is blocked inside 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // of dnsResolve() waiting for a response from the origin thread. 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (d) Nothing is running on the worker thread, however the host resolver has 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // a pending DNS request which upon completion will restart the script 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // execution. 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (e) The worker thread has a pending task to restart execution, which was 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // posted after the DNS dependency was resolved and saved to local cache. 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (f) The script execution completed entirely, and posted a task to the 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // origin thread to notify the caller. 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |cancelled_| is read on both the origin thread and worker thread. The 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // code that runs on the worker thread is littered with checks on 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |cancelled_| to break out early. 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cancelled_.Set(); 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReleaseCallback(); 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (pending_dns_) { 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host_resolver()->CancelRequest(pending_dns_); 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_dns_ = NULL; 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The worker thread might be blocked waiting for DNS. 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_.Signal(); 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) owned_self_reference_ = NULL; 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)LoadState ProxyResolverV8Tracing::Job::GetLoadState() const { 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnOriginThread(); 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (pending_dns_) 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT; 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return LOAD_STATE_RESOLVING_PROXY_FOR_URL; 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProxyResolverV8Tracing::Job::~Job() { 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!pending_dns_); 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(callback_.is_null()); 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::CheckIsOnWorkerThread() const { 38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_EQ(base::MessageLoop::current(), parent_->thread_->message_loop()); 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::CheckIsOnOriginThread() const { 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(origin_loop_->BelongsToCurrentThread()); 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::SetCallback( 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CompletionCallback& callback) { 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnOriginThread(); 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(callback_.is_null()); 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parent_->num_outstanding_callbacks_++; 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_ = callback; 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::ReleaseCallback() { 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnOriginThread(); 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback_.is_null()); 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_GT(parent_->num_outstanding_callbacks_, 0); 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parent_->num_outstanding_callbacks_--; 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_.Reset(); 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For good measure, clear this other user-owned pointer. 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) user_results_ = NULL; 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProxyResolverV8* ProxyResolverV8Tracing::Job::v8_resolver() { 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return parent_->v8_resolver_.get(); 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)base::MessageLoop* ProxyResolverV8Tracing::Job::worker_loop() { 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return parent_->thread_->message_loop(); 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HostResolver* ProxyResolverV8Tracing::Job::host_resolver() { 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return parent_->host_resolver_; 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProxyResolverErrorObserver* ProxyResolverV8Tracing::Job::error_observer() { 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return parent_->error_observer_.get(); 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NetLog* ProxyResolverV8Tracing::Job::net_log() { 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return parent_->net_log_; 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::NotifyCaller(int result) { 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnWorkerThread(); 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) origin_loop_->PostTask( 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&Job::NotifyCallerOnOriginLoop, this, result)); 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::NotifyCallerOnOriginLoop(int result) { 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnOriginThread(); 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (cancelled_.IsSet()) 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback_.is_null()); 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!pending_dns_); 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (operation_ == GET_PROXY_FOR_URL) { 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *user_results_ = results_; 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // There is only ever 1 outstanding SET_PAC_SCRIPT job. It needs to be 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // tracked to support cancellation. 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (operation_ == SET_PAC_SCRIPT) { 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(parent_->set_pac_script_job_.get(), this); 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parent_->set_pac_script_job_ = NULL; 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CompletionCallback callback = callback_; 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReleaseCallback(); 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(result); 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) owned_self_reference_ = NULL; 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::Start(Operation op, bool blocking_dns, 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CompletionCallback& callback) { 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnOriginThread(); 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) operation_ = op; 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) blocking_dns_ = blocking_dns; 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetCallback(callback); 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) owned_self_reference_ = this; 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) worker_loop()->PostTask(FROM_HERE, 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) blocking_dns_ ? base::Bind(&Job::ExecuteBlocking, this) : 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&Job::ExecuteNonBlocking, this)); 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::ExecuteBlocking() { 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnWorkerThread(); 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(blocking_dns_); 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (cancelled_.IsSet()) 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyCaller(ExecuteProxyResolver()); 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::ExecuteNonBlocking() { 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnWorkerThread(); 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!blocking_dns_); 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (cancelled_.IsSet()) 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Reset state for the current execution. 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) abandoned_ = false; 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_dns_ = 0; 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) alerts_and_errors_.clear(); 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) alerts_and_errors_byte_cost_ = 0; 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) should_restart_with_blocking_dns_ = false; 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int result = ExecuteProxyResolver(); 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (should_restart_with_blocking_dns_) { 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!blocking_dns_); 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(abandoned_); 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) blocking_dns_ = true; 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExecuteBlocking(); 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (abandoned_) 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchBufferedAlertsAndErrors(); 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyCaller(result); 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int ProxyResolverV8Tracing::Job::ExecuteProxyResolver() { 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JSBindings* prev_bindings = v8_resolver()->js_bindings(); 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) v8_resolver()->set_js_bindings(this); 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int result = ERR_UNEXPECTED; // Initialized to silence warnings. 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (operation_) { 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case SET_PAC_SCRIPT: 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result = v8_resolver()->SetPacScript( 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) script_data_, CompletionCallback()); 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case GET_PROXY_FOR_URL: 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result = v8_resolver()->GetProxyForURL( 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url_, 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Important: Do not write directly into |user_results_|, since if the 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // request were to be cancelled from the origin thread, must guarantee 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that |user_results_| is not accessed anymore. 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &results_, 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CompletionCallback(), 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL, 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound_net_log_); 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) v8_resolver()->set_js_bindings(prev_bindings); 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result; 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ProxyResolverV8Tracing::Job::ResolveDns(const std::string& host, 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResolveDnsOperation op, 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* output, 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* terminate) { 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (cancelled_.IsSet()) { 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *terminate = true; 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((op == DNS_RESOLVE || op == DNS_RESOLVE_EX) && host.empty()) { 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // a DNS resolve with an empty hostname is considered an error. 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return blocking_dns_ ? 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResolveDnsBlocking(host, op, output) : 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResolveDnsNonBlocking(host, op, output, terminate); 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ProxyResolverV8Tracing::Job::Alert(const base::string16& message) { 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HandleAlertOrError(true, -1, message); 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::OnError(int line_number, 572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::string16& error) { 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HandleAlertOrError(false, line_number, error); 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ProxyResolverV8Tracing::Job::ResolveDnsBlocking(const std::string& host, 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResolveDnsOperation op, 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* output) { 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnWorkerThread(); 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check if the DNS result for this host has already been cached. 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool rv; 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (GetDnsFromLocalCache(host, op, output, &rv)) { 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Yay, cache hit! 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dns_cache_.size() >= kMaxUniqueResolveDnsPerExec) { 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Safety net for scripts with unexpectedly many DNS calls. 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We will continue running to completion, but will fail every 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // subsequent DNS request. 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!PostDnsOperationAndWait(host, op, NULL)) 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; // Was cancelled. 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(GetDnsFromLocalCache(host, op, output, &rv)); 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ProxyResolverV8Tracing::Job::ResolveDnsNonBlocking(const std::string& host, 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResolveDnsOperation op, 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* output, 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* terminate) { 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnWorkerThread(); 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (abandoned_) { 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If this execution was already abandoned can fail right away. Only 1 DNS 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // dependency will be traced at a time (for more predictable outcomes). 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_dns_ += 1; 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check if the DNS result for this host has already been cached. 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool rv; 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (GetDnsFromLocalCache(host, op, output, &rv)) { 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Yay, cache hit! 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (num_dns_ <= last_num_dns_) { 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The sequence of DNS operations is different from last time! 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScheduleRestartWithBlockingDns(); 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *terminate = true; 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dns_cache_.size() >= kMaxUniqueResolveDnsPerExec) { 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Safety net for scripts with unexpectedly many DNS calls. 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!should_restart_with_blocking_dns_); 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool completed_synchronously; 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!PostDnsOperationAndWait(host, op, &completed_synchronously)) 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; // Was cancelled. 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (completed_synchronously) { 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(GetDnsFromLocalCache(host, op, output, &rv)); 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Otherwise if the result was not in the cache, then a DNS request has 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // been started. Abandon this invocation of FindProxyForURL(), it will be 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // restarted once the DNS request completes. 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) abandoned_ = true; 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *terminate = true; 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_num_dns_ = num_dns_; 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ProxyResolverV8Tracing::Job::PostDnsOperationAndWait( 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& host, ResolveDnsOperation op, 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* completed_synchronously) { 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Post the DNS request to the origin thread. 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!pending_dns_); 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_dns_host_ = host; 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_dns_op_ = op; 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) origin_loop_->PostTask(FROM_HERE, base::Bind(&Job::DoDnsOperation, this)); 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_.Wait(); 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_.Reset(); 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (cancelled_.IsSet()) 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (completed_synchronously) 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *completed_synchronously = pending_dns_completed_synchronously_; 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::DoDnsOperation() { 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnOriginThread(); 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!pending_dns_); 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (cancelled_.IsSet()) 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HostResolver::RequestHandle dns_request = NULL; 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int result = host_resolver()->Resolve( 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MakeDnsRequestInfo(pending_dns_host_, pending_dns_op_), 6873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DEFAULT_PRIORITY, 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &pending_dns_addresses_, 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&Job::OnDnsOperationComplete, this), 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &dns_request, 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound_net_log_); 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_dns_completed_synchronously_ = result != ERR_IO_PENDING; 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check if the request was cancelled as a side-effect of calling into the 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // HostResolver. This isn't the ordinary execution flow, however it is 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // exercised by unit-tests. 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (cancelled_.IsSet()) { 6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!pending_dns_completed_synchronously_) 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host_resolver()->CancelRequest(dns_request); 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (pending_dns_completed_synchronously_) { 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnDnsOperationComplete(result); 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(dns_request); 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_dns_ = dns_request; 7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // OnDnsOperationComplete() will be called by host resolver on completion. 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!blocking_dns_) { 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The worker thread always blocks waiting to see if the result can be 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // serviced from cache before restarting. 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_.Signal(); 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::OnDnsOperationComplete(int result) { 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnOriginThread(); 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!cancelled_.IsSet()); 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(pending_dns_completed_synchronously_ == (pending_dns_ == NULL)); 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SaveDnsToLocalCache(pending_dns_host_, pending_dns_op_, result, 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_dns_addresses_); 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_dns_ = NULL; 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (blocking_dns_) { 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_.Signal(); 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!blocking_dns_ && !pending_dns_completed_synchronously_) { 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Restart. This time it should make more progress due to having 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // cached items. 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) worker_loop()->PostTask(FROM_HERE, 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&Job::ExecuteNonBlocking, this)); 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::ScheduleRestartWithBlockingDns() { 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnWorkerThread(); 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!should_restart_with_blocking_dns_); 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!abandoned_); 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!blocking_dns_); 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) abandoned_ = true; 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The restart will happen after ExecuteNonBlocking() finishes. 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) should_restart_with_blocking_dns_ = true; 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ProxyResolverV8Tracing::Job::GetDnsFromLocalCache( 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& host, 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResolveDnsOperation op, 7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* output, 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* return_value) { 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnWorkerThread(); 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DnsCache::const_iterator it = dns_cache_.find(MakeDnsCacheKey(host, op)); 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it == dns_cache_.end()) 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *output = it->second; 7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *return_value = !it->second.empty(); 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::SaveDnsToLocalCache( 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& host, 7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResolveDnsOperation op, 7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int net_error, 7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const net::AddressList& addresses) { 7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnOriginThread(); 7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Serialize the result into a string to save to the cache. 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string cache_value; 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (net_error != OK) { 7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cache_value = std::string(); 7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (op == DNS_RESOLVE || op == MY_IP_ADDRESS) { 7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // dnsResolve() and myIpAddress() are expected to return a single IP 7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // address. 7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cache_value = addresses.front().ToStringWithoutPort(); 7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The *Ex versions are expected to return a semi-colon separated list. 7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (AddressList::const_iterator iter = addresses.begin(); 7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != addresses.end(); ++iter) { 7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cache_value.empty()) 7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cache_value += ";"; 7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cache_value += iter->ToStringWithoutPort(); 7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dns_cache_[MakeDnsCacheKey(host, op)] = cache_value; 7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HostResolver::RequestInfo ProxyResolverV8Tracing::Job::MakeDnsRequestInfo( 8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& host, ResolveDnsOperation op) { 8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HostPortPair host_port = HostPortPair(host, 80); 8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (op == MY_IP_ADDRESS || op == MY_IP_ADDRESS_EX) { 8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host_port.set_host(GetHostName()); 8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HostResolver::RequestInfo info(host_port); 808116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Flag myIpAddress requests. 809116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (op == MY_IP_ADDRESS || op == MY_IP_ADDRESS_EX) { 810116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO: Provide a RequestInfo construction mechanism that does not 811116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // require a hostname and sets is_my_ip_address to true instead of this. 812116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch info.set_is_my_ip_address(true); 813116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The non-ex flavors are limited to IPv4 results. 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (op == MY_IP_ADDRESS || op == DNS_RESOLVE) { 8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info.set_address_family(ADDRESS_FAMILY_IPV4); 8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return info; 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string ProxyResolverV8Tracing::Job::MakeDnsCacheKey( 8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& host, ResolveDnsOperation op) { 8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf("%d:%s", op, host.c_str()); 8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ProxyResolverV8Tracing::Job::HandleAlertOrError( 828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_alert, 829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int line_number, 830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::string16& message) { 8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnWorkerThread(); 8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (cancelled_.IsSet()) 8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (blocking_dns_) { 8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // In blocking DNS mode the events can be dispatched immediately. 8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchAlertOrError(is_alert, line_number, message); 8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Otherwise in nonblocking mode, buffer all the messages until 8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the end. 8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (abandoned_) 8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) alerts_and_errors_byte_cost_ += sizeof(AlertOrError) + message.size() * 2; 8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If there have been lots of messages, enqueing could be expensive on 8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // memory. Consider a script which does megabytes worth of alerts(). 8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Avoid this by falling back to blocking mode. 8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (alerts_and_errors_byte_cost_ > kMaxAlertsAndErrorsBytes) { 8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScheduleRestartWithBlockingDns(); 8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AlertOrError entry = {is_alert, line_number, message}; 8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) alerts_and_errors_.push_back(entry); 8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::DispatchBufferedAlertsAndErrors() { 8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnWorkerThread(); 8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!blocking_dns_); 8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!abandoned_); 8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < alerts_and_errors_.size(); ++i) { 8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const AlertOrError& x = alerts_and_errors_[i]; 8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchAlertOrError(x.is_alert, x.line_number, x.message); 8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::DispatchAlertOrError( 874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_alert, int line_number, const base::string16& message) { 8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnWorkerThread(); 8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note that the handling of cancellation is racy with regard to 8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // alerts/errors. The request might get cancelled shortly after this 8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // check! (There is no lock being held to guarantee otherwise). 8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If this happens, then some information will get written to the NetLog 8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // needlessly, however the NetLog will still be alive so it shouldn't cause 8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // problems. 8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (cancelled_.IsSet()) 8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_alert) { 8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ------------------- 8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // alert 8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ------------------- 8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "PAC-alert: " << message; 8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send to the NetLog. 8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LogEventToCurrentRequestAndGlobally( 8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NetLog::TYPE_PAC_JAVASCRIPT_ALERT, 8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NetLog::StringCallback("message", &message)); 8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ------------------- 8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // error 9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ------------------- 9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (line_number == -1) 9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "PAC-error: " << message; 9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "PAC-error: " << "line: " << line_number << ": " << message; 9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send the error to the NetLog. 9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LogEventToCurrentRequestAndGlobally( 9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NetLog::TYPE_PAC_JAVASCRIPT_ERROR, 9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&NetLogErrorCallback, line_number, &message)); 9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (error_observer()) 9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_observer()->OnPACScriptError(line_number, message); 9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::Job::LogEventToCurrentRequestAndGlobally( 9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NetLog::EventType type, 9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const NetLog::ParametersCallback& parameters_callback) { 9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckIsOnWorkerThread(); 9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound_net_log_.AddEvent(type, parameters_callback); 9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Emit to the global NetLog event stream. 9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (net_log()) 9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net_log()->AddGlobalEntry(type, parameters_callback); 9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProxyResolverV8Tracing::ProxyResolverV8Tracing( 9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HostResolver* host_resolver, 9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyResolverErrorObserver* error_observer, 9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NetLog* net_log) 9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : ProxyResolver(true /*expects_pac_bytes*/), 9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host_resolver_(host_resolver), 9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_observer_(error_observer), 9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net_log_(net_log), 9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_outstanding_callbacks_(0) { 9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(host_resolver); 9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Start up the thread. 9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_.reset(new base::Thread("Proxy resolver")); 939116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Thread::Options options; 940116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch options.timer_slack = base::TIMER_SLACK_MAXIMUM; 941116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CHECK(thread_->StartWithOptions(options)); 9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) v8_resolver_.reset(new ProxyResolverV8); 9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProxyResolverV8Tracing::~ProxyResolverV8Tracing() { 9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note, all requests should have been cancelled. 948868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CHECK(!set_pac_script_job_.get()); 9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_EQ(0, num_outstanding_callbacks_); 9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Join the worker thread. See http://crbug.com/69710. Note that we call 9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Stop() here instead of simply clearing thread_ since there may be pending 9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // callbacks on the worker thread which want to dereference thread_. 9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ThreadRestrictions::ScopedAllowIO allow_io; 9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_->Stop(); 9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int ProxyResolverV8Tracing::GetProxyForURL(const GURL& url, 9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyInfo* results, 9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CompletionCallback& callback, 9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RequestHandle* request, 9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BoundNetLog& net_log) { 9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 965868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!set_pac_script_job_.get()); 9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<Job> job = new Job(this); 9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (request) 9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *request = job.get(); 9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) job->StartGetProxyForURL(url, results, net_log, callback); 9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ERR_IO_PENDING; 9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::CancelRequest(RequestHandle request) { 9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Job* job = reinterpret_cast<Job*>(request); 9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) job->Cancel(); 9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)LoadState ProxyResolverV8Tracing::GetLoadState(RequestHandle request) const { 9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Job* job = reinterpret_cast<Job*>(request); 9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return job->GetLoadState(); 9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyResolverV8Tracing::CancelSetPacScript() { 987868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(set_pac_script_job_.get()); 9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) set_pac_script_job_->Cancel(); 9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) set_pac_script_job_ = NULL; 9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int ProxyResolverV8Tracing::SetPacScript( 9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const scoped_refptr<ProxyResolverScriptData>& script_data, 9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CompletionCallback& callback) { 9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note that there should not be any outstanding (non-cancelled) Jobs when 9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // setting the PAC script (ProxyService should guarantee this). If there are, 10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // then they might complete in strange ways after the new script is set. 1001868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!set_pac_script_job_.get()); 10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_EQ(0, num_outstanding_callbacks_); 10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) set_pac_script_job_ = new Job(this); 10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) set_pac_script_job_->StartSetPacScript(script_data, callback); 10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ERR_IO_PENDING; 10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace net 1011