Chromium Code Reviews| 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..af9d9cc7537f75193b0ad226cc3387f2e01af05a 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,8 +67,6 @@ 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. |
|
eroman
2015/05/05 00:04:55
SetPacScript() no longer applies. please change th
Sam McNally
2015/05/05 01:31:36
Done.
|
| // |
| @@ -79,17 +81,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 |
| // 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 +132,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 +154,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 +230,7 @@ class ProxyResolverV8Tracing::Job |
| // The ProxyResolverV8Tracing which spawned this Job. |
| // 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 +261,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 +321,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 +406,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 +441,7 @@ void ProxyResolverV8Tracing::Job::Cancel() { |
| owned_self_reference_ = NULL; |
| } |
| -LoadState ProxyResolverV8Tracing::Job::GetLoadState() const { |
| +LoadState Job::GetLoadState() const { |
| CheckIsOnOriginThread(); |
| if (pending_dns_) |
| @@ -375,59 +450,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 +509,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 +522,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 +529,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 +540,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 +555,7 @@ void ProxyResolverV8Tracing::Job::ExecuteBlocking() { |
| NotifyCaller(ExecuteProxyResolver()); |
| } |
| -void ProxyResolverV8Tracing::Job::ExecuteNonBlocking() { |
| +void Job::ExecuteNonBlocking() { |
| CheckIsOnWorkerThread(); |
| DCHECK(!blocking_dns_); |
| @@ -518,18 +586,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 +612,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 +639,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 +673,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 +726,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 +747,7 @@ bool ProxyResolverV8Tracing::Job::PostDnsOperationAndWait( |
| return true; |
| } |
| -void ProxyResolverV8Tracing::Job::DoDnsOperation() { |
| +void Job::DoDnsOperation() { |
| CheckIsOnOriginThread(); |
| DCHECK(!pending_dns_); |
| @@ -708,8 +779,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 +793,7 @@ void ProxyResolverV8Tracing::Job::DoDnsOperation() { |
| } |
| } |
| -void ProxyResolverV8Tracing::Job::OnDnsOperationComplete(int result) { |
| +void Job::OnDnsOperationComplete(int result) { |
| CheckIsOnOriginThread(); |
| DCHECK(!cancelled_.IsSet()); |
| @@ -732,10 +803,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 +817,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 +835,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 +850,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 +878,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 +900,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 +939,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 +950,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 +994,7 @@ void ProxyResolverV8Tracing::Job::DispatchAlertOrError( |
| } |
| } |
| -void ProxyResolverV8Tracing::Job::LogEventToCurrentRequestAndGlobally( |
| +void Job::LogEventToCurrentRequestAndGlobally( |
| NetLog::EventType type, |
| const NetLog::ParametersCallback& parameters_callback) { |
| CheckIsOnWorkerThread(); |
| @@ -937,46 +1006,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 +1035,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 +1056,139 @@ 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) |
| + : ProxyResolverFactory(true), |
| + host_resolver_(host_resolver), |
| + net_log_(net_log), |
| + load_state_changed_callback_(callback) { |
| +} |
| + |
| +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_, CreateErrorObserver(), 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 |