Index: net/proxy/proxy_resolver_v8_tracing.cc |
diff --git a/net/proxy/proxy_resolver_v8_tracing.cc b/net/proxy/proxy_resolver_v8_tracing.cc |
index ce5cb5f881c9d34e391acf01091d5e5241a7c390..18bf179af6fe427e462e0c1a4f9f6f9fa1f69c96 100644 |
--- a/net/proxy/proxy_resolver_v8_tracing.cc |
+++ b/net/proxy/proxy_resolver_v8_tracing.cc |
@@ -4,6 +4,10 @@ |
#include "net/proxy/proxy_resolver_v8_tracing.h" |
+#include <map> |
+#include <string> |
+#include <vector> |
+ |
#include "base/bind.h" |
#include "base/message_loop/message_loop_proxy.h" |
#include "base/strings/stringprintf.h" |
@@ -63,10 +67,9 @@ base::Value* NetLogErrorCallback(int line_number, |
return dict; |
} |
-} // namespace |
- |
// The Job class is responsible for executing GetProxyForURL() and |
-// SetPacScript(), since both of these operations share similar code. |
+// creating ProxyResolverV8 instances, since both of these operations share |
+// similar code. |
// |
// The DNS for these operations can operate in either blocking or |
// non-blocking mode. Blocking mode is used as a fallback when the PAC script |
@@ -79,17 +82,41 @@ base::Value* NetLogErrorCallback(int line_number, |
// The lifetime of Jobs does not exceed that of the ProxyResolverV8Tracing that |
// spawned it. Destruction might happen on either the origin thread or the |
// worker thread. |
-class ProxyResolverV8Tracing::Job |
- : public base::RefCountedThreadSafe<ProxyResolverV8Tracing::Job>, |
- public ProxyResolverV8::JSBindings { |
+class Job : public base::RefCountedThreadSafe<Job>, |
+ public ProxyResolverV8::JSBindings { |
public: |
+ struct Params { |
+ Params( |
+ const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner, |
+ HostResolver* host_resolver, |
+ ProxyResolverErrorObserver* error_observer, |
+ NetLog* net_log, |
+ ProxyResolver::LoadStateChangedCallback on_load_state_changed, |
+ int* num_outstanding_callbacks) |
+ : v8_resolver(nullptr), |
+ worker_task_runner(worker_task_runner), |
+ host_resolver(host_resolver), |
+ error_observer(error_observer), |
+ net_log(net_log), |
+ on_load_state_changed(on_load_state_changed), |
+ num_outstanding_callbacks(num_outstanding_callbacks) {} |
+ |
+ ProxyResolverV8* v8_resolver; |
+ scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner; |
+ HostResolver* host_resolver; |
+ ProxyResolverErrorObserver* error_observer; |
+ NetLog* net_log; |
+ ProxyResolver::LoadStateChangedCallback on_load_state_changed; |
+ int* num_outstanding_callbacks; |
+ }; |
// |parent| is non-owned. It is the ProxyResolverV8Tracing that spawned this |
eroman
2015/05/15 07:39:37
comment no longer applicable
Sam McNally
2015/05/15 09:20:19
Done.
|
// Job, and must oulive it. |
- explicit Job(ProxyResolverV8Tracing* parent); |
+ explicit Job(const Params* params); |
// Called from origin thread. |
- void StartSetPacScript( |
+ void StartCreateV8Resolver( |
const scoped_refptr<ProxyResolverScriptData>& script_data, |
+ scoped_ptr<ProxyResolverV8>* resolver, |
const CompletionCallback& callback); |
// Called from origin thread. |
@@ -106,10 +133,10 @@ class ProxyResolverV8Tracing::Job |
private: |
typedef std::map<std::string, std::string> DnsCache; |
- friend class base::RefCountedThreadSafe<ProxyResolverV8Tracing::Job>; |
+ friend class base::RefCountedThreadSafe<Job>; |
enum Operation { |
- SET_PAC_SCRIPT, |
+ CREATE_V8_RESOLVER, |
GET_PROXY_FOR_URL, |
}; |
@@ -128,7 +155,7 @@ class ProxyResolverV8Tracing::Job |
void ReleaseCallback(); |
ProxyResolverV8* v8_resolver(); |
- base::MessageLoop* worker_loop(); |
+ const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner(); |
HostResolver* host_resolver(); |
ProxyResolverErrorObserver* error_observer(); |
NetLog* net_log(); |
@@ -204,7 +231,7 @@ class ProxyResolverV8Tracing::Job |
// The ProxyResolverV8Tracing which spawned this Job. |
eroman
2015/05/15 07:39:38
comment no longer applicable
Sam McNally
2015/05/15 09:20:19
Done.
|
// Initialized on origin thread and then accessed from both threads. |
- ProxyResolverV8Tracing* parent_; |
+ const Params* const params_; |
// The callback to run (on the origin thread) when the Job finishes. |
// Should only be accessed from origin thread. |
@@ -235,10 +262,11 @@ class ProxyResolverV8Tracing::Job |
scoped_refptr<Job> owned_self_reference_; |
// ------------------------------------------------------- |
- // State specific to SET_PAC_SCRIPT. |
+ // State specific to CREATE_V8_RESOLVER. |
// ------------------------------------------------------- |
scoped_refptr<ProxyResolverScriptData> script_data_; |
+ scoped_ptr<ProxyResolverV8>* resolver_out_; |
// ------------------------------------------------------- |
// State specific to GET_PROXY_FOR_URL. |
@@ -294,34 +322,82 @@ class ProxyResolverV8Tracing::Job |
AddressList pending_dns_addresses_; |
}; |
-ProxyResolverV8Tracing::Job::Job(ProxyResolverV8Tracing* parent) |
+class ProxyResolverV8Tracing : public ProxyResolver, |
+ public base::NonThreadSafe { |
+ public: |
+ // Constructs a ProxyResolver that will issue DNS requests through |
+ // |job_params->host_resolver|, forward Javascript errors through |
+ // |error_observer|, and log Javascript errors and alerts to |
+ // |job_params->net_log|. When the LoadState for a request changes, |
+ // |job_params->on_load_state_changed| will be invoked with the RequestHandle |
+ // for that request with the new LoadState. |
+ // |
+ // Note that the constructor takes ownership of |error_observer|, whereas |
+ // |job_params->host_resolver| and |job_params->net_log| are expected to |
+ // outlive |this|. |
+ ProxyResolverV8Tracing(scoped_ptr<ProxyResolverErrorObserver> error_observer, |
+ scoped_ptr<base::Thread> thread, |
+ scoped_ptr<ProxyResolverV8> resolver, |
+ scoped_ptr<Job::Params> job_params); |
+ |
+ ~ProxyResolverV8Tracing() override; |
+ |
+ // ProxyResolver implementation: |
+ int GetProxyForURL(const GURL& url, |
+ ProxyInfo* results, |
+ const CompletionCallback& callback, |
+ RequestHandle* request, |
+ const BoundNetLog& net_log) override; |
+ void CancelRequest(RequestHandle request) override; |
+ LoadState GetLoadState(RequestHandle request) const override; |
+ void CancelSetPacScript() override; |
+ int SetPacScript(const scoped_refptr<ProxyResolverScriptData>& script_data, |
+ const CompletionCallback& callback) override; |
+ |
+ private: |
+ // The worker thread on which the ProxyResolverV8 will be run. |
+ scoped_ptr<base::Thread> thread_; |
+ scoped_ptr<ProxyResolverV8> v8_resolver_; |
+ |
+ scoped_ptr<ProxyResolverErrorObserver> error_observer_; |
+ |
+ scoped_ptr<Job::Params> job_params_; |
+ |
+ // The number of outstanding (non-cancelled) jobs. |
+ int num_outstanding_callbacks_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ProxyResolverV8Tracing); |
+}; |
+ |
+Job::Job(const Job::Params* params) |
: origin_loop_(base::MessageLoopProxy::current()), |
- parent_(parent), |
+ params_(params), |
event_(true, false), |
last_num_dns_(0), |
pending_dns_(NULL) { |
CheckIsOnOriginThread(); |
} |
-void ProxyResolverV8Tracing::Job::StartSetPacScript( |
+void Job::StartCreateV8Resolver( |
const scoped_refptr<ProxyResolverScriptData>& script_data, |
+ scoped_ptr<ProxyResolverV8>* resolver, |
const CompletionCallback& callback) { |
CheckIsOnOriginThread(); |
+ resolver_out_ = resolver; |
script_data_ = script_data; |
// Script initialization uses blocking DNS since there isn't any |
// advantage to using non-blocking mode here. That is because the |
// parent ProxyService can't submit any ProxyResolve requests until |
// initialization has completed successfully! |
- Start(SET_PAC_SCRIPT, true /*blocking*/, callback); |
+ Start(CREATE_V8_RESOLVER, true /*blocking*/, callback); |
} |
-void ProxyResolverV8Tracing::Job::StartGetProxyForURL( |
- const GURL& url, |
- ProxyInfo* results, |
- const BoundNetLog& net_log, |
- const CompletionCallback& callback) { |
+void Job::StartGetProxyForURL(const GURL& url, |
+ ProxyInfo* results, |
+ const BoundNetLog& net_log, |
+ const CompletionCallback& callback) { |
CheckIsOnOriginThread(); |
url_ = url; |
@@ -331,7 +407,7 @@ void ProxyResolverV8Tracing::Job::StartGetProxyForURL( |
Start(GET_PROXY_FOR_URL, false /*non-blocking*/, callback); |
} |
-void ProxyResolverV8Tracing::Job::Cancel() { |
+void Job::Cancel() { |
CheckIsOnOriginThread(); |
// There are several possibilities to consider for cancellation: |
@@ -366,7 +442,7 @@ void ProxyResolverV8Tracing::Job::Cancel() { |
owned_self_reference_ = NULL; |
} |
-LoadState ProxyResolverV8Tracing::Job::GetLoadState() const { |
+LoadState Job::GetLoadState() const { |
CheckIsOnOriginThread(); |
if (pending_dns_) |
@@ -375,59 +451,58 @@ LoadState ProxyResolverV8Tracing::Job::GetLoadState() const { |
return LOAD_STATE_RESOLVING_PROXY_FOR_URL; |
} |
-ProxyResolverV8Tracing::Job::~Job() { |
+Job::~Job() { |
DCHECK(!pending_dns_); |
DCHECK(callback_.is_null()); |
} |
-void ProxyResolverV8Tracing::Job::CheckIsOnWorkerThread() const { |
- DCHECK_EQ(base::MessageLoop::current(), parent_->thread_->message_loop()); |
+void Job::CheckIsOnWorkerThread() const { |
+ DCHECK(params_->worker_task_runner->BelongsToCurrentThread()); |
} |
-void ProxyResolverV8Tracing::Job::CheckIsOnOriginThread() const { |
+void Job::CheckIsOnOriginThread() const { |
DCHECK(origin_loop_->BelongsToCurrentThread()); |
} |
-void ProxyResolverV8Tracing::Job::SetCallback( |
- const CompletionCallback& callback) { |
+void Job::SetCallback(const CompletionCallback& callback) { |
CheckIsOnOriginThread(); |
DCHECK(callback_.is_null()); |
- parent_->num_outstanding_callbacks_++; |
+ (*params_->num_outstanding_callbacks)++; |
callback_ = callback; |
} |
-void ProxyResolverV8Tracing::Job::ReleaseCallback() { |
+void Job::ReleaseCallback() { |
CheckIsOnOriginThread(); |
DCHECK(!callback_.is_null()); |
- CHECK_GT(parent_->num_outstanding_callbacks_, 0); |
- parent_->num_outstanding_callbacks_--; |
+ CHECK_GT(*params_->num_outstanding_callbacks, 0); |
+ (*params_->num_outstanding_callbacks)--; |
callback_.Reset(); |
// For good measure, clear this other user-owned pointer. |
user_results_ = NULL; |
} |
-ProxyResolverV8* ProxyResolverV8Tracing::Job::v8_resolver() { |
- return parent_->v8_resolver_.get(); |
+ProxyResolverV8* Job::v8_resolver() { |
+ return params_->v8_resolver; |
} |
-base::MessageLoop* ProxyResolverV8Tracing::Job::worker_loop() { |
- return parent_->thread_->message_loop(); |
+const scoped_refptr<base::SingleThreadTaskRunner>& Job::worker_task_runner() { |
+ return params_->worker_task_runner; |
} |
-HostResolver* ProxyResolverV8Tracing::Job::host_resolver() { |
- return parent_->host_resolver_; |
+HostResolver* Job::host_resolver() { |
+ return params_->host_resolver; |
} |
-ProxyResolverErrorObserver* ProxyResolverV8Tracing::Job::error_observer() { |
- return parent_->error_observer_.get(); |
+ProxyResolverErrorObserver* Job::error_observer() { |
+ return params_->error_observer; |
} |
-NetLog* ProxyResolverV8Tracing::Job::net_log() { |
- return parent_->net_log_; |
+NetLog* Job::net_log() { |
+ return params_->net_log; |
} |
-void ProxyResolverV8Tracing::Job::NotifyCaller(int result) { |
+void Job::NotifyCaller(int result) { |
CheckIsOnWorkerThread(); |
origin_loop_->PostTask( |
@@ -435,7 +510,7 @@ void ProxyResolverV8Tracing::Job::NotifyCaller(int result) { |
base::Bind(&Job::NotifyCallerOnOriginLoop, this, result)); |
} |
-void ProxyResolverV8Tracing::Job::NotifyCallerOnOriginLoop(int result) { |
+void Job::NotifyCallerOnOriginLoop(int result) { |
CheckIsOnOriginThread(); |
if (cancelled_.IsSet()) |
@@ -448,13 +523,6 @@ void ProxyResolverV8Tracing::Job::NotifyCallerOnOriginLoop(int result) { |
*user_results_ = results_; |
} |
- // There is only ever 1 outstanding SET_PAC_SCRIPT job. It needs to be |
- // tracked to support cancellation. |
- if (operation_ == SET_PAC_SCRIPT) { |
- DCHECK_EQ(parent_->set_pac_script_job_.get(), this); |
- parent_->set_pac_script_job_ = NULL; |
- } |
- |
CompletionCallback callback = callback_; |
ReleaseCallback(); |
callback.Run(result); |
@@ -462,8 +530,9 @@ void ProxyResolverV8Tracing::Job::NotifyCallerOnOriginLoop(int result) { |
owned_self_reference_ = NULL; |
} |
-void ProxyResolverV8Tracing::Job::Start(Operation op, bool blocking_dns, |
- const CompletionCallback& callback) { |
+void Job::Start(Operation op, |
+ bool blocking_dns, |
+ const CompletionCallback& callback) { |
CheckIsOnOriginThread(); |
operation_ = op; |
@@ -472,12 +541,12 @@ void ProxyResolverV8Tracing::Job::Start(Operation op, bool blocking_dns, |
owned_self_reference_ = this; |
- worker_loop()->PostTask(FROM_HERE, |
- blocking_dns_ ? base::Bind(&Job::ExecuteBlocking, this) : |
- base::Bind(&Job::ExecuteNonBlocking, this)); |
+ worker_task_runner()->PostTask( |
+ FROM_HERE, blocking_dns_ ? base::Bind(&Job::ExecuteBlocking, this) |
+ : base::Bind(&Job::ExecuteNonBlocking, this)); |
} |
-void ProxyResolverV8Tracing::Job::ExecuteBlocking() { |
+void Job::ExecuteBlocking() { |
CheckIsOnWorkerThread(); |
DCHECK(blocking_dns_); |
@@ -487,7 +556,7 @@ void ProxyResolverV8Tracing::Job::ExecuteBlocking() { |
NotifyCaller(ExecuteProxyResolver()); |
} |
-void ProxyResolverV8Tracing::Job::ExecuteNonBlocking() { |
+void Job::ExecuteNonBlocking() { |
CheckIsOnWorkerThread(); |
DCHECK(!blocking_dns_); |
@@ -518,18 +587,23 @@ void ProxyResolverV8Tracing::Job::ExecuteNonBlocking() { |
NotifyCaller(result); |
} |
-int ProxyResolverV8Tracing::Job::ExecuteProxyResolver() { |
- JSBindings* prev_bindings = v8_resolver()->js_bindings(); |
- v8_resolver()->set_js_bindings(this); |
- |
+int Job::ExecuteProxyResolver() { |
int result = ERR_UNEXPECTED; // Initialized to silence warnings. |
switch (operation_) { |
- case SET_PAC_SCRIPT: |
- result = v8_resolver()->SetPacScript( |
- script_data_, CompletionCallback()); |
+ case CREATE_V8_RESOLVER: { |
+ scoped_ptr<ProxyResolverV8> resolver(new ProxyResolverV8); |
+ resolver->set_js_bindings(this); |
+ result = resolver->SetPacScript(script_data_, CompletionCallback()); |
+ resolver->set_js_bindings(nullptr); |
+ if (result == OK) |
+ *resolver_out_ = resolver.Pass(); |
break; |
- case GET_PROXY_FOR_URL: |
+ } |
+ case GET_PROXY_FOR_URL: { |
+ JSBindings* prev_bindings = v8_resolver()->js_bindings(); |
+ v8_resolver()->set_js_bindings(this); |
+ |
result = v8_resolver()->GetProxyForURL( |
url_, |
// Important: Do not write directly into |user_results_|, since if the |
@@ -539,18 +613,18 @@ int ProxyResolverV8Tracing::Job::ExecuteProxyResolver() { |
CompletionCallback(), |
NULL, |
bound_net_log_); |
+ v8_resolver()->set_js_bindings(prev_bindings); |
break; |
+ } |
} |
- v8_resolver()->set_js_bindings(prev_bindings); |
- |
return result; |
} |
-bool ProxyResolverV8Tracing::Job::ResolveDns(const std::string& host, |
- ResolveDnsOperation op, |
- std::string* output, |
- bool* terminate) { |
+bool Job::ResolveDns(const std::string& host, |
+ ResolveDnsOperation op, |
+ std::string* output, |
+ bool* terminate) { |
if (cancelled_.IsSet()) { |
*terminate = true; |
return false; |
@@ -566,18 +640,17 @@ bool ProxyResolverV8Tracing::Job::ResolveDns(const std::string& host, |
ResolveDnsNonBlocking(host, op, output, terminate); |
} |
-void ProxyResolverV8Tracing::Job::Alert(const base::string16& message) { |
+void Job::Alert(const base::string16& message) { |
HandleAlertOrError(true, -1, message); |
} |
-void ProxyResolverV8Tracing::Job::OnError(int line_number, |
- const base::string16& error) { |
+void Job::OnError(int line_number, const base::string16& error) { |
HandleAlertOrError(false, line_number, error); |
} |
-bool ProxyResolverV8Tracing::Job::ResolveDnsBlocking(const std::string& host, |
- ResolveDnsOperation op, |
- std::string* output) { |
+bool Job::ResolveDnsBlocking(const std::string& host, |
+ ResolveDnsOperation op, |
+ std::string* output) { |
CheckIsOnWorkerThread(); |
// Check if the DNS result for this host has already been cached. |
@@ -601,10 +674,10 @@ bool ProxyResolverV8Tracing::Job::ResolveDnsBlocking(const std::string& host, |
return rv; |
} |
-bool ProxyResolverV8Tracing::Job::ResolveDnsNonBlocking(const std::string& host, |
- ResolveDnsOperation op, |
- std::string* output, |
- bool* terminate) { |
+bool Job::ResolveDnsNonBlocking(const std::string& host, |
+ ResolveDnsOperation op, |
+ std::string* output, |
+ bool* terminate) { |
CheckIsOnWorkerThread(); |
if (abandoned_) { |
@@ -654,10 +727,9 @@ bool ProxyResolverV8Tracing::Job::ResolveDnsNonBlocking(const std::string& host, |
return false; |
} |
-bool ProxyResolverV8Tracing::Job::PostDnsOperationAndWait( |
- const std::string& host, ResolveDnsOperation op, |
- bool* completed_synchronously) { |
- |
+bool Job::PostDnsOperationAndWait(const std::string& host, |
+ ResolveDnsOperation op, |
+ bool* completed_synchronously) { |
// Post the DNS request to the origin thread. |
DCHECK(!pending_dns_); |
pending_dns_host_ = host; |
@@ -676,7 +748,7 @@ bool ProxyResolverV8Tracing::Job::PostDnsOperationAndWait( |
return true; |
} |
-void ProxyResolverV8Tracing::Job::DoDnsOperation() { |
+void Job::DoDnsOperation() { |
CheckIsOnOriginThread(); |
DCHECK(!pending_dns_); |
@@ -708,8 +780,8 @@ void ProxyResolverV8Tracing::Job::DoDnsOperation() { |
} else { |
DCHECK(dns_request); |
pending_dns_ = dns_request; |
- if (!parent_->on_load_state_changed_.is_null()) { |
- parent_->on_load_state_changed_.Run( |
+ if (!params_->on_load_state_changed.is_null()) { |
+ params_->on_load_state_changed.Run( |
this, LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT); |
} |
// OnDnsOperationComplete() will be called by host resolver on completion. |
@@ -722,7 +794,7 @@ void ProxyResolverV8Tracing::Job::DoDnsOperation() { |
} |
} |
-void ProxyResolverV8Tracing::Job::OnDnsOperationComplete(int result) { |
+void Job::OnDnsOperationComplete(int result) { |
CheckIsOnOriginThread(); |
DCHECK(!cancelled_.IsSet()); |
@@ -732,10 +804,10 @@ void ProxyResolverV8Tracing::Job::OnDnsOperationComplete(int result) { |
pending_dns_addresses_); |
pending_dns_ = NULL; |
- if (!parent_->on_load_state_changed_.is_null() && |
+ if (!params_->on_load_state_changed.is_null() && |
!pending_dns_completed_synchronously_ && !cancelled_.IsSet()) { |
- parent_->on_load_state_changed_.Run(this, |
- LOAD_STATE_RESOLVING_PROXY_FOR_URL); |
+ params_->on_load_state_changed.Run(this, |
+ LOAD_STATE_RESOLVING_PROXY_FOR_URL); |
} |
if (blocking_dns_) { |
@@ -746,12 +818,12 @@ void ProxyResolverV8Tracing::Job::OnDnsOperationComplete(int result) { |
if (!blocking_dns_ && !pending_dns_completed_synchronously_) { |
// Restart. This time it should make more progress due to having |
// cached items. |
- worker_loop()->PostTask(FROM_HERE, |
- base::Bind(&Job::ExecuteNonBlocking, this)); |
+ worker_task_runner()->PostTask(FROM_HERE, |
+ base::Bind(&Job::ExecuteNonBlocking, this)); |
} |
} |
-void ProxyResolverV8Tracing::Job::ScheduleRestartWithBlockingDns() { |
+void Job::ScheduleRestartWithBlockingDns() { |
CheckIsOnWorkerThread(); |
DCHECK(!should_restart_with_blocking_dns_); |
@@ -764,11 +836,10 @@ void ProxyResolverV8Tracing::Job::ScheduleRestartWithBlockingDns() { |
should_restart_with_blocking_dns_ = true; |
} |
-bool ProxyResolverV8Tracing::Job::GetDnsFromLocalCache( |
- const std::string& host, |
- ResolveDnsOperation op, |
- std::string* output, |
- bool* return_value) { |
+bool Job::GetDnsFromLocalCache(const std::string& host, |
+ ResolveDnsOperation op, |
+ std::string* output, |
+ bool* return_value) { |
CheckIsOnWorkerThread(); |
DnsCache::const_iterator it = dns_cache_.find(MakeDnsCacheKey(host, op)); |
@@ -780,11 +851,10 @@ bool ProxyResolverV8Tracing::Job::GetDnsFromLocalCache( |
return true; |
} |
-void ProxyResolverV8Tracing::Job::SaveDnsToLocalCache( |
- const std::string& host, |
- ResolveDnsOperation op, |
- int net_error, |
- const AddressList& addresses) { |
+void Job::SaveDnsToLocalCache(const std::string& host, |
+ ResolveDnsOperation op, |
+ int net_error, |
+ const AddressList& addresses) { |
CheckIsOnOriginThread(); |
// Serialize the result into a string to save to the cache. |
@@ -809,8 +879,8 @@ void ProxyResolverV8Tracing::Job::SaveDnsToLocalCache( |
} |
// static |
-HostResolver::RequestInfo ProxyResolverV8Tracing::Job::MakeDnsRequestInfo( |
- const std::string& host, ResolveDnsOperation op) { |
+HostResolver::RequestInfo Job::MakeDnsRequestInfo(const std::string& host, |
+ ResolveDnsOperation op) { |
HostPortPair host_port = HostPortPair(host, 80); |
if (op == MY_IP_ADDRESS || op == MY_IP_ADDRESS_EX) { |
host_port.set_host(GetHostName()); |
@@ -831,15 +901,14 @@ HostResolver::RequestInfo ProxyResolverV8Tracing::Job::MakeDnsRequestInfo( |
return info; |
} |
-std::string ProxyResolverV8Tracing::Job::MakeDnsCacheKey( |
- const std::string& host, ResolveDnsOperation op) { |
+std::string Job::MakeDnsCacheKey(const std::string& host, |
+ ResolveDnsOperation op) { |
return base::StringPrintf("%d:%s", op, host.c_str()); |
} |
-void ProxyResolverV8Tracing::Job::HandleAlertOrError( |
- bool is_alert, |
- int line_number, |
- const base::string16& message) { |
+void Job::HandleAlertOrError(bool is_alert, |
+ int line_number, |
+ const base::string16& message) { |
CheckIsOnWorkerThread(); |
if (cancelled_.IsSet()) |
@@ -871,7 +940,7 @@ void ProxyResolverV8Tracing::Job::HandleAlertOrError( |
alerts_and_errors_.push_back(entry); |
} |
-void ProxyResolverV8Tracing::Job::DispatchBufferedAlertsAndErrors() { |
+void Job::DispatchBufferedAlertsAndErrors() { |
CheckIsOnWorkerThread(); |
DCHECK(!blocking_dns_); |
DCHECK(!abandoned_); |
@@ -882,8 +951,9 @@ void ProxyResolverV8Tracing::Job::DispatchBufferedAlertsAndErrors() { |
} |
} |
-void ProxyResolverV8Tracing::Job::DispatchAlertOrError( |
- bool is_alert, int line_number, const base::string16& message) { |
+void Job::DispatchAlertOrError(bool is_alert, |
+ int line_number, |
+ const base::string16& message) { |
CheckIsOnWorkerThread(); |
// Note that the handling of cancellation is racy with regard to |
@@ -925,7 +995,7 @@ void ProxyResolverV8Tracing::Job::DispatchAlertOrError( |
} |
} |
-void ProxyResolverV8Tracing::Job::LogEventToCurrentRequestAndGlobally( |
+void Job::LogEventToCurrentRequestAndGlobally( |
NetLog::EventType type, |
const NetLog::ParametersCallback& parameters_callback) { |
CheckIsOnWorkerThread(); |
@@ -937,46 +1007,26 @@ void ProxyResolverV8Tracing::Job::LogEventToCurrentRequestAndGlobally( |
} |
ProxyResolverV8Tracing::ProxyResolverV8Tracing( |
- HostResolver* host_resolver, |
- ProxyResolverErrorObserver* error_observer, |
- NetLog* net_log) |
- : ProxyResolverV8Tracing(host_resolver, |
- error_observer, |
- net_log, |
- LoadStateChangedCallback()) { |
-} |
- |
-ProxyResolverV8Tracing::ProxyResolverV8Tracing( |
- HostResolver* host_resolver, |
- ProxyResolverErrorObserver* error_observer, |
- NetLog* net_log, |
- const LoadStateChangedCallback& on_load_state_changed) |
+ scoped_ptr<ProxyResolverErrorObserver> error_observer, |
+ scoped_ptr<base::Thread> thread, |
+ scoped_ptr<ProxyResolverV8> resolver, |
+ scoped_ptr<Job::Params> job_params) |
: ProxyResolver(true /*expects_pac_bytes*/), |
- host_resolver_(host_resolver), |
- error_observer_(error_observer), |
- net_log_(net_log), |
- num_outstanding_callbacks_(0), |
- on_load_state_changed_(on_load_state_changed) { |
- DCHECK(host_resolver); |
- // Start up the thread. |
- thread_.reset(new base::Thread("Proxy resolver")); |
- base::Thread::Options options; |
- options.timer_slack = base::TIMER_SLACK_MAXIMUM; |
- CHECK(thread_->StartWithOptions(options)); |
- |
- v8_resolver_.reset(new ProxyResolverV8); |
+ thread_(thread.Pass()), |
+ v8_resolver_(resolver.Pass()), |
+ error_observer_(error_observer.Pass()), |
+ job_params_(job_params.Pass()), |
+ num_outstanding_callbacks_(0) { |
+ job_params_->num_outstanding_callbacks = &num_outstanding_callbacks_; |
} |
ProxyResolverV8Tracing::~ProxyResolverV8Tracing() { |
// Note, all requests should have been cancelled. |
- CHECK(!set_pac_script_job_.get()); |
CHECK_EQ(0, num_outstanding_callbacks_); |
- // Join the worker thread. See http://crbug.com/69710. Note that we call |
- // Stop() here instead of simply clearing thread_ since there may be pending |
- // callbacks on the worker thread which want to dereference thread_. |
+ // Join the worker thread. See http://crbug.com/69710. |
base::ThreadRestrictions::ScopedAllowIO allow_io; |
- thread_->Stop(); |
+ thread_.reset(); |
} |
int ProxyResolverV8Tracing::GetProxyForURL(const GURL& url, |
@@ -986,9 +1036,8 @@ int ProxyResolverV8Tracing::GetProxyForURL(const GURL& url, |
const BoundNetLog& net_log) { |
DCHECK(CalledOnValidThread()); |
DCHECK(!callback.is_null()); |
- DCHECK(!set_pac_script_job_.get()); |
- scoped_refptr<Job> job = new Job(this); |
+ scoped_refptr<Job> job = new Job(job_params_.get()); |
if (request) |
*request = job.get(); |
@@ -1008,27 +1057,144 @@ LoadState ProxyResolverV8Tracing::GetLoadState(RequestHandle request) const { |
} |
void ProxyResolverV8Tracing::CancelSetPacScript() { |
- DCHECK(set_pac_script_job_.get()); |
- set_pac_script_job_->Cancel(); |
- set_pac_script_job_ = NULL; |
+ NOTREACHED(); |
} |
int ProxyResolverV8Tracing::SetPacScript( |
const scoped_refptr<ProxyResolverScriptData>& script_data, |
const CompletionCallback& callback) { |
- DCHECK(CalledOnValidThread()); |
- DCHECK(!callback.is_null()); |
+ NOTREACHED(); |
+ return ERR_NOT_IMPLEMENTED; |
+} |
- // Note that there should not be any outstanding (non-cancelled) Jobs when |
- // setting the PAC script (ProxyService should guarantee this). If there are, |
- // then they might complete in strange ways after the new script is set. |
- DCHECK(!set_pac_script_job_.get()); |
- CHECK_EQ(0, num_outstanding_callbacks_); |
+} // namespace |
- set_pac_script_job_ = new Job(this); |
- set_pac_script_job_->StartSetPacScript(script_data, callback); |
+class ProxyResolverFactoryV8Tracing::CreateJob |
+ : public ProxyResolverFactory::Request { |
+ public: |
+ CreateJob(ProxyResolverFactoryV8Tracing* factory, |
+ HostResolver* host_resolver, |
+ scoped_ptr<ProxyResolverErrorObserver> error_observer, |
+ NetLog* net_log, |
+ const ProxyResolver::LoadStateChangedCallback& |
+ load_state_changed_callback, |
+ const scoped_refptr<ProxyResolverScriptData>& pac_script, |
+ scoped_ptr<ProxyResolver>* resolver_out, |
+ const CompletionCallback& callback) |
+ : factory_(factory), |
+ thread_(new base::Thread("Proxy Resolver")), |
+ error_observer_(error_observer.Pass()), |
+ resolver_out_(resolver_out), |
+ callback_(callback), |
+ num_outstanding_callbacks_(0) { |
+ // Start up the thread. |
+ base::Thread::Options options; |
+ options.timer_slack = base::TIMER_SLACK_MAXIMUM; |
+ CHECK(thread_->StartWithOptions(options)); |
+ job_params_.reset(new Job::Params( |
+ thread_->task_runner(), host_resolver, error_observer_.get(), net_log, |
+ load_state_changed_callback, &num_outstanding_callbacks_)); |
+ create_resolver_job_ = new Job(job_params_.get()); |
+ create_resolver_job_->StartCreateV8Resolver( |
+ pac_script, &v8_resolver_, |
+ base::Bind( |
+ &ProxyResolverFactoryV8Tracing::CreateJob::OnV8ResolverCreated, |
+ base::Unretained(this))); |
+ } |
+ ~CreateJob() override { |
+ if (factory_) { |
+ factory_->RemoveJob(this); |
+ DCHECK(create_resolver_job_); |
+ create_resolver_job_->Cancel(); |
+ StopWorkerThread(); |
+ } |
+ DCHECK_EQ(0, num_outstanding_callbacks_); |
+ } |
+ |
+ void FactoryDestroyed() { |
+ factory_ = nullptr; |
+ create_resolver_job_->Cancel(); |
+ create_resolver_job_ = nullptr; |
+ StopWorkerThread(); |
+ } |
+ |
+ private: |
+ void OnV8ResolverCreated(int error) { |
+ DCHECK(factory_); |
+ if (error == OK) { |
+ job_params_->v8_resolver = v8_resolver_.get(); |
+ resolver_out_->reset( |
+ new ProxyResolverV8Tracing(error_observer_.Pass(), thread_.Pass(), |
+ v8_resolver_.Pass(), job_params_.Pass())); |
+ } else { |
+ StopWorkerThread(); |
+ } |
+ |
+ factory_->RemoveJob(this); |
+ factory_ = nullptr; |
+ create_resolver_job_ = nullptr; |
+ callback_.Run(error); |
+ } |
+ |
+ void StopWorkerThread() { |
+ // Join the worker thread. See http://crbug.com/69710. |
+ base::ThreadRestrictions::ScopedAllowIO allow_io; |
+ thread_.reset(); |
+ } |
+ |
+ ProxyResolverFactoryV8Tracing* factory_; |
+ scoped_ptr<base::Thread> thread_; |
+ scoped_ptr<ProxyResolverErrorObserver> error_observer_; |
+ scoped_ptr<Job::Params> job_params_; |
+ scoped_refptr<Job> create_resolver_job_; |
+ scoped_ptr<ProxyResolverV8> v8_resolver_; |
+ scoped_ptr<ProxyResolver>* resolver_out_; |
+ const CompletionCallback callback_; |
+ int num_outstanding_callbacks_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CreateJob); |
+}; |
+ |
+ProxyResolverFactoryV8Tracing::ProxyResolverFactoryV8Tracing( |
+ HostResolver* host_resolver, |
+ NetLog* net_log, |
+ const ProxyResolver::LoadStateChangedCallback& callback, |
+ const base::Callback<scoped_ptr<ProxyResolverErrorObserver>()>& |
+ error_observer_factory) |
+ : ProxyResolverFactory(true), |
+ host_resolver_(host_resolver), |
+ net_log_(net_log), |
+ load_state_changed_callback_(callback), |
+ error_observer_factory_(error_observer_factory) { |
+} |
+ |
+ProxyResolverFactoryV8Tracing::~ProxyResolverFactoryV8Tracing() { |
+ for (auto job : jobs_) { |
+ job->FactoryDestroyed(); |
+ } |
+} |
+ |
+// ProxyResolverFactory override. |
+int ProxyResolverFactoryV8Tracing::CreateProxyResolver( |
+ const scoped_refptr<ProxyResolverScriptData>& pac_script, |
+ scoped_ptr<ProxyResolver>* resolver, |
+ const CompletionCallback& callback, |
+ scoped_ptr<Request>* request) { |
+ scoped_ptr<CreateJob> job(new CreateJob( |
+ this, host_resolver_, |
+ error_observer_factory_.is_null() ? nullptr |
+ : error_observer_factory_.Run(), |
+ net_log_, load_state_changed_callback_, pac_script, resolver, callback)); |
+ jobs_.insert(job.get()); |
+ *request = job.Pass(); |
return ERR_IO_PENDING; |
} |
+void ProxyResolverFactoryV8Tracing::RemoveJob( |
+ ProxyResolverFactoryV8Tracing::CreateJob* job) { |
+ size_t erased = jobs_.erase(job); |
+ DCHECK_EQ(1u, erased); |
+} |
+ |
} // namespace net |