Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/proxy/proxy_resolver_v8_tracing.h" | 5 #include "net/proxy/proxy_resolver_v8_tracing.h" |
| 6 | 6 |
| 7 #include <map> | |
| 8 #include <string> | |
| 9 #include <vector> | |
| 10 | |
| 7 #include "base/bind.h" | 11 #include "base/bind.h" |
| 8 #include "base/message_loop/message_loop_proxy.h" | 12 #include "base/message_loop/message_loop_proxy.h" |
| 9 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
| 10 #include "base/synchronization/cancellation_flag.h" | 14 #include "base/synchronization/cancellation_flag.h" |
| 11 #include "base/synchronization/waitable_event.h" | 15 #include "base/synchronization/waitable_event.h" |
| 12 #include "base/threading/thread.h" | 16 #include "base/threading/thread.h" |
| 13 #include "base/threading/thread_restrictions.h" | 17 #include "base/threading/thread_restrictions.h" |
| 14 #include "base/values.h" | 18 #include "base/values.h" |
| 15 #include "net/base/address_list.h" | 19 #include "net/base/address_list.h" |
| 16 #include "net/base/net_errors.h" | 20 #include "net/base/net_errors.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 56 // Returns event parameters for a PAC error message (line number + message). | 60 // Returns event parameters for a PAC error message (line number + message). |
| 57 base::Value* NetLogErrorCallback(int line_number, | 61 base::Value* NetLogErrorCallback(int line_number, |
| 58 const base::string16* message, | 62 const base::string16* message, |
| 59 NetLogCaptureMode /* capture_mode */) { | 63 NetLogCaptureMode /* capture_mode */) { |
| 60 base::DictionaryValue* dict = new base::DictionaryValue(); | 64 base::DictionaryValue* dict = new base::DictionaryValue(); |
| 61 dict->SetInteger("line_number", line_number); | 65 dict->SetInteger("line_number", line_number); |
| 62 dict->SetString("message", *message); | 66 dict->SetString("message", *message); |
| 63 return dict; | 67 return dict; |
| 64 } | 68 } |
| 65 | 69 |
| 66 } // namespace | |
| 67 | |
| 68 // The Job class is responsible for executing GetProxyForURL() and | 70 // The Job class is responsible for executing GetProxyForURL() and |
| 69 // SetPacScript(), since both of these operations share similar code. | 71 // 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.
| |
| 70 // | 72 // |
| 71 // The DNS for these operations can operate in either blocking or | 73 // The DNS for these operations can operate in either blocking or |
| 72 // non-blocking mode. Blocking mode is used as a fallback when the PAC script | 74 // non-blocking mode. Blocking mode is used as a fallback when the PAC script |
| 73 // seems to be misbehaving under the tracing optimization. | 75 // seems to be misbehaving under the tracing optimization. |
| 74 // | 76 // |
| 75 // Note that this class runs on both the origin thread and a worker | 77 // Note that this class runs on both the origin thread and a worker |
| 76 // thread. Most methods are expected to be used exclusively on one thread | 78 // thread. Most methods are expected to be used exclusively on one thread |
| 77 // or the other. | 79 // or the other. |
| 78 // | 80 // |
| 79 // The lifetime of Jobs does not exceed that of the ProxyResolverV8Tracing that | 81 // The lifetime of Jobs does not exceed that of the ProxyResolverV8Tracing that |
| 80 // spawned it. Destruction might happen on either the origin thread or the | 82 // spawned it. Destruction might happen on either the origin thread or the |
| 81 // worker thread. | 83 // worker thread. |
| 82 class ProxyResolverV8Tracing::Job | 84 class Job : public base::RefCountedThreadSafe<Job>, |
| 83 : public base::RefCountedThreadSafe<ProxyResolverV8Tracing::Job>, | 85 public ProxyResolverV8::JSBindings { |
| 84 public ProxyResolverV8::JSBindings { | |
| 85 public: | 86 public: |
| 87 struct Params { | |
| 88 Params( | |
| 89 const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner, | |
| 90 HostResolver* host_resolver, | |
| 91 ProxyResolverErrorObserver* error_observer, | |
| 92 NetLog* net_log, | |
| 93 ProxyResolver::LoadStateChangedCallback on_load_state_changed, | |
| 94 int* num_outstanding_callbacks) | |
| 95 : v8_resolver(nullptr), | |
| 96 worker_task_runner(worker_task_runner), | |
| 97 host_resolver(host_resolver), | |
| 98 error_observer(error_observer), | |
| 99 net_log(net_log), | |
| 100 on_load_state_changed(on_load_state_changed), | |
| 101 num_outstanding_callbacks(num_outstanding_callbacks) {} | |
| 102 | |
| 103 ProxyResolverV8* v8_resolver; | |
| 104 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner; | |
| 105 HostResolver* host_resolver; | |
| 106 ProxyResolverErrorObserver* error_observer; | |
| 107 NetLog* net_log; | |
| 108 ProxyResolver::LoadStateChangedCallback on_load_state_changed; | |
| 109 int* num_outstanding_callbacks; | |
| 110 }; | |
| 86 // |parent| is non-owned. It is the ProxyResolverV8Tracing that spawned this | 111 // |parent| is non-owned. It is the ProxyResolverV8Tracing that spawned this |
| 87 // Job, and must oulive it. | 112 // Job, and must oulive it. |
| 88 explicit Job(ProxyResolverV8Tracing* parent); | 113 explicit Job(const Params* params); |
| 89 | 114 |
| 90 // Called from origin thread. | 115 // Called from origin thread. |
| 91 void StartSetPacScript( | 116 void StartCreateV8Resolver( |
| 92 const scoped_refptr<ProxyResolverScriptData>& script_data, | 117 const scoped_refptr<ProxyResolverScriptData>& script_data, |
| 118 scoped_ptr<ProxyResolverV8>* resolver, | |
| 93 const CompletionCallback& callback); | 119 const CompletionCallback& callback); |
| 94 | 120 |
| 95 // Called from origin thread. | 121 // Called from origin thread. |
| 96 void StartGetProxyForURL(const GURL& url, | 122 void StartGetProxyForURL(const GURL& url, |
| 97 ProxyInfo* results, | 123 ProxyInfo* results, |
| 98 const BoundNetLog& net_log, | 124 const BoundNetLog& net_log, |
| 99 const CompletionCallback& callback); | 125 const CompletionCallback& callback); |
| 100 | 126 |
| 101 // Called from origin thread. | 127 // Called from origin thread. |
| 102 void Cancel(); | 128 void Cancel(); |
| 103 | 129 |
| 104 // Called from origin thread. | 130 // Called from origin thread. |
| 105 LoadState GetLoadState() const; | 131 LoadState GetLoadState() const; |
| 106 | 132 |
| 107 private: | 133 private: |
| 108 typedef std::map<std::string, std::string> DnsCache; | 134 typedef std::map<std::string, std::string> DnsCache; |
| 109 friend class base::RefCountedThreadSafe<ProxyResolverV8Tracing::Job>; | 135 friend class base::RefCountedThreadSafe<Job>; |
| 110 | 136 |
| 111 enum Operation { | 137 enum Operation { |
| 112 SET_PAC_SCRIPT, | 138 CREATE_V8_RESOLVER, |
| 113 GET_PROXY_FOR_URL, | 139 GET_PROXY_FOR_URL, |
| 114 }; | 140 }; |
| 115 | 141 |
| 116 struct AlertOrError { | 142 struct AlertOrError { |
| 117 bool is_alert; | 143 bool is_alert; |
| 118 int line_number; | 144 int line_number; |
| 119 base::string16 message; | 145 base::string16 message; |
| 120 }; | 146 }; |
| 121 | 147 |
| 122 ~Job() override; | 148 ~Job() override; |
| 123 | 149 |
| 124 void CheckIsOnWorkerThread() const; | 150 void CheckIsOnWorkerThread() const; |
| 125 void CheckIsOnOriginThread() const; | 151 void CheckIsOnOriginThread() const; |
| 126 | 152 |
| 127 void SetCallback(const CompletionCallback& callback); | 153 void SetCallback(const CompletionCallback& callback); |
| 128 void ReleaseCallback(); | 154 void ReleaseCallback(); |
| 129 | 155 |
| 130 ProxyResolverV8* v8_resolver(); | 156 ProxyResolverV8* v8_resolver(); |
| 131 base::MessageLoop* worker_loop(); | 157 const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner(); |
| 132 HostResolver* host_resolver(); | 158 HostResolver* host_resolver(); |
| 133 ProxyResolverErrorObserver* error_observer(); | 159 ProxyResolverErrorObserver* error_observer(); |
| 134 NetLog* net_log(); | 160 NetLog* net_log(); |
| 135 | 161 |
| 136 // Invokes the user's callback. | 162 // Invokes the user's callback. |
| 137 void NotifyCaller(int result); | 163 void NotifyCaller(int result); |
| 138 void NotifyCallerOnOriginLoop(int result); | 164 void NotifyCallerOnOriginLoop(int result); |
| 139 | 165 |
| 140 void Start(Operation op, bool blocking_dns, | 166 void Start(Operation op, bool blocking_dns, |
| 141 const CompletionCallback& callback); | 167 const CompletionCallback& callback); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 197 void LogEventToCurrentRequestAndGlobally( | 223 void LogEventToCurrentRequestAndGlobally( |
| 198 NetLog::EventType type, | 224 NetLog::EventType type, |
| 199 const NetLog::ParametersCallback& parameters_callback); | 225 const NetLog::ParametersCallback& parameters_callback); |
| 200 | 226 |
| 201 // The thread which called into ProxyResolverV8Tracing, and on which the | 227 // The thread which called into ProxyResolverV8Tracing, and on which the |
| 202 // completion callback is expected to run. | 228 // completion callback is expected to run. |
| 203 scoped_refptr<base::MessageLoopProxy> origin_loop_; | 229 scoped_refptr<base::MessageLoopProxy> origin_loop_; |
| 204 | 230 |
| 205 // The ProxyResolverV8Tracing which spawned this Job. | 231 // The ProxyResolverV8Tracing which spawned this Job. |
| 206 // Initialized on origin thread and then accessed from both threads. | 232 // Initialized on origin thread and then accessed from both threads. |
| 207 ProxyResolverV8Tracing* parent_; | 233 const Params* const params_; |
| 208 | 234 |
| 209 // The callback to run (on the origin thread) when the Job finishes. | 235 // The callback to run (on the origin thread) when the Job finishes. |
| 210 // Should only be accessed from origin thread. | 236 // Should only be accessed from origin thread. |
| 211 CompletionCallback callback_; | 237 CompletionCallback callback_; |
| 212 | 238 |
| 213 // Flag to indicate whether the request has been cancelled. | 239 // Flag to indicate whether the request has been cancelled. |
| 214 base::CancellationFlag cancelled_; | 240 base::CancellationFlag cancelled_; |
| 215 | 241 |
| 216 // The operation that this Job is running. | 242 // The operation that this Job is running. |
| 217 // Initialized on origin thread and then accessed from both threads. | 243 // Initialized on origin thread and then accessed from both threads. |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 228 | 254 |
| 229 // Map of DNS operations completed so far. Written into on the origin thread | 255 // Map of DNS operations completed so far. Written into on the origin thread |
| 230 // and read on the worker thread. | 256 // and read on the worker thread. |
| 231 DnsCache dns_cache_; | 257 DnsCache dns_cache_; |
| 232 | 258 |
| 233 // The job holds a reference to itself to ensure that it remains alive until | 259 // The job holds a reference to itself to ensure that it remains alive until |
| 234 // either completion or cancellation. | 260 // either completion or cancellation. |
| 235 scoped_refptr<Job> owned_self_reference_; | 261 scoped_refptr<Job> owned_self_reference_; |
| 236 | 262 |
| 237 // ------------------------------------------------------- | 263 // ------------------------------------------------------- |
| 238 // State specific to SET_PAC_SCRIPT. | 264 // State specific to CREATE_V8_RESOLVER. |
| 239 // ------------------------------------------------------- | 265 // ------------------------------------------------------- |
| 240 | 266 |
| 241 scoped_refptr<ProxyResolverScriptData> script_data_; | 267 scoped_refptr<ProxyResolverScriptData> script_data_; |
| 268 scoped_ptr<ProxyResolverV8>* resolver_out_; | |
| 242 | 269 |
| 243 // ------------------------------------------------------- | 270 // ------------------------------------------------------- |
| 244 // State specific to GET_PROXY_FOR_URL. | 271 // State specific to GET_PROXY_FOR_URL. |
| 245 // ------------------------------------------------------- | 272 // ------------------------------------------------------- |
| 246 | 273 |
| 247 ProxyInfo* user_results_; // Owned by caller, lives on origin thread. | 274 ProxyInfo* user_results_; // Owned by caller, lives on origin thread. |
| 248 GURL url_; | 275 GURL url_; |
| 249 ProxyInfo results_; | 276 ProxyInfo results_; |
| 250 BoundNetLog bound_net_log_; | 277 BoundNetLog bound_net_log_; |
| 251 | 278 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 287 // These are the inputs to DoDnsOperation(). Written on the worker thread, | 314 // These are the inputs to DoDnsOperation(). Written on the worker thread, |
| 288 // read by the origin thread. | 315 // read by the origin thread. |
| 289 std::string pending_dns_host_; | 316 std::string pending_dns_host_; |
| 290 ResolveDnsOperation pending_dns_op_; | 317 ResolveDnsOperation pending_dns_op_; |
| 291 | 318 |
| 292 // This contains the resolved address list that DoDnsOperation() fills in. | 319 // This contains the resolved address list that DoDnsOperation() fills in. |
| 293 // Used exclusively on the origin thread. | 320 // Used exclusively on the origin thread. |
| 294 AddressList pending_dns_addresses_; | 321 AddressList pending_dns_addresses_; |
| 295 }; | 322 }; |
| 296 | 323 |
| 297 ProxyResolverV8Tracing::Job::Job(ProxyResolverV8Tracing* parent) | 324 class ProxyResolverV8Tracing : public ProxyResolver, |
| 325 public base::NonThreadSafe { | |
| 326 public: | |
| 327 // Constructs a ProxyResolver that will issue DNS requests through | |
| 328 // |job_params->host_resolver|, forward Javascript errors through | |
| 329 // |error_observer|, and log Javascript errors and alerts to | |
| 330 // |job_params->net_log|. When the LoadState for a request changes, | |
| 331 // |job_params->on_load_state_changed| will be invoked with the RequestHandle | |
| 332 // for that request with the new LoadState. | |
| 333 // | |
| 334 // Note that the constructor takes ownership of |error_observer|, whereas | |
| 335 // |job_params->host_resolver| and |job_params->net_log| are expected to | |
| 336 // outlive |this|. | |
| 337 ProxyResolverV8Tracing(scoped_ptr<ProxyResolverErrorObserver> error_observer, | |
| 338 scoped_ptr<base::Thread> thread, | |
| 339 scoped_ptr<ProxyResolverV8> resolver, | |
| 340 scoped_ptr<Job::Params> job_params); | |
| 341 | |
| 342 ~ProxyResolverV8Tracing() override; | |
| 343 | |
| 344 // ProxyResolver implementation: | |
| 345 int GetProxyForURL(const GURL& url, | |
| 346 ProxyInfo* results, | |
| 347 const CompletionCallback& callback, | |
| 348 RequestHandle* request, | |
| 349 const BoundNetLog& net_log) override; | |
| 350 void CancelRequest(RequestHandle request) override; | |
| 351 LoadState GetLoadState(RequestHandle request) const override; | |
| 352 void CancelSetPacScript() override; | |
| 353 int SetPacScript(const scoped_refptr<ProxyResolverScriptData>& script_data, | |
| 354 const CompletionCallback& callback) override; | |
| 355 | |
| 356 private: | |
| 357 // The worker thread on which the ProxyResolverV8 will be run. | |
| 358 scoped_ptr<base::Thread> thread_; | |
| 359 scoped_ptr<ProxyResolverV8> v8_resolver_; | |
| 360 | |
| 361 scoped_ptr<ProxyResolverErrorObserver> error_observer_; | |
| 362 | |
| 363 scoped_ptr<Job::Params> job_params_; | |
| 364 | |
| 365 // The number of outstanding (non-cancelled) jobs. | |
| 366 int num_outstanding_callbacks_; | |
| 367 | |
| 368 DISALLOW_COPY_AND_ASSIGN(ProxyResolverV8Tracing); | |
| 369 }; | |
| 370 | |
| 371 Job::Job(const Job::Params* params) | |
| 298 : origin_loop_(base::MessageLoopProxy::current()), | 372 : origin_loop_(base::MessageLoopProxy::current()), |
| 299 parent_(parent), | 373 params_(params), |
| 300 event_(true, false), | 374 event_(true, false), |
| 301 last_num_dns_(0), | 375 last_num_dns_(0), |
| 302 pending_dns_(NULL) { | 376 pending_dns_(NULL) { |
| 303 CheckIsOnOriginThread(); | 377 CheckIsOnOriginThread(); |
| 304 } | 378 } |
| 305 | 379 |
| 306 void ProxyResolverV8Tracing::Job::StartSetPacScript( | 380 void Job::StartCreateV8Resolver( |
| 307 const scoped_refptr<ProxyResolverScriptData>& script_data, | 381 const scoped_refptr<ProxyResolverScriptData>& script_data, |
| 382 scoped_ptr<ProxyResolverV8>* resolver, | |
| 308 const CompletionCallback& callback) { | 383 const CompletionCallback& callback) { |
| 309 CheckIsOnOriginThread(); | 384 CheckIsOnOriginThread(); |
| 310 | 385 |
| 386 resolver_out_ = resolver; | |
| 311 script_data_ = script_data; | 387 script_data_ = script_data; |
| 312 | 388 |
| 313 // Script initialization uses blocking DNS since there isn't any | 389 // Script initialization uses blocking DNS since there isn't any |
| 314 // advantage to using non-blocking mode here. That is because the | 390 // advantage to using non-blocking mode here. That is because the |
| 315 // parent ProxyService can't submit any ProxyResolve requests until | 391 // parent ProxyService can't submit any ProxyResolve requests until |
| 316 // initialization has completed successfully! | 392 // initialization has completed successfully! |
| 317 Start(SET_PAC_SCRIPT, true /*blocking*/, callback); | 393 Start(CREATE_V8_RESOLVER, true /*blocking*/, callback); |
| 318 } | 394 } |
| 319 | 395 |
| 320 void ProxyResolverV8Tracing::Job::StartGetProxyForURL( | 396 void Job::StartGetProxyForURL(const GURL& url, |
| 321 const GURL& url, | 397 ProxyInfo* results, |
| 322 ProxyInfo* results, | 398 const BoundNetLog& net_log, |
| 323 const BoundNetLog& net_log, | 399 const CompletionCallback& callback) { |
| 324 const CompletionCallback& callback) { | |
| 325 CheckIsOnOriginThread(); | 400 CheckIsOnOriginThread(); |
| 326 | 401 |
| 327 url_ = url; | 402 url_ = url; |
| 328 user_results_ = results; | 403 user_results_ = results; |
| 329 bound_net_log_ = net_log; | 404 bound_net_log_ = net_log; |
| 330 | 405 |
| 331 Start(GET_PROXY_FOR_URL, false /*non-blocking*/, callback); | 406 Start(GET_PROXY_FOR_URL, false /*non-blocking*/, callback); |
| 332 } | 407 } |
| 333 | 408 |
| 334 void ProxyResolverV8Tracing::Job::Cancel() { | 409 void Job::Cancel() { |
| 335 CheckIsOnOriginThread(); | 410 CheckIsOnOriginThread(); |
| 336 | 411 |
| 337 // There are several possibilities to consider for cancellation: | 412 // There are several possibilities to consider for cancellation: |
| 338 // (a) The job has been posted to the worker thread, however script execution | 413 // (a) The job has been posted to the worker thread, however script execution |
| 339 // has not yet started. | 414 // has not yet started. |
| 340 // (b) The script is executing on the worker thread. | 415 // (b) The script is executing on the worker thread. |
| 341 // (c) The script is executing on the worker thread, however is blocked inside | 416 // (c) The script is executing on the worker thread, however is blocked inside |
| 342 // of dnsResolve() waiting for a response from the origin thread. | 417 // of dnsResolve() waiting for a response from the origin thread. |
| 343 // (d) Nothing is running on the worker thread, however the host resolver has | 418 // (d) Nothing is running on the worker thread, however the host resolver has |
| 344 // a pending DNS request which upon completion will restart the script | 419 // a pending DNS request which upon completion will restart the script |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 359 host_resolver()->CancelRequest(pending_dns_); | 434 host_resolver()->CancelRequest(pending_dns_); |
| 360 pending_dns_ = NULL; | 435 pending_dns_ = NULL; |
| 361 } | 436 } |
| 362 | 437 |
| 363 // The worker thread might be blocked waiting for DNS. | 438 // The worker thread might be blocked waiting for DNS. |
| 364 event_.Signal(); | 439 event_.Signal(); |
| 365 | 440 |
| 366 owned_self_reference_ = NULL; | 441 owned_self_reference_ = NULL; |
| 367 } | 442 } |
| 368 | 443 |
| 369 LoadState ProxyResolverV8Tracing::Job::GetLoadState() const { | 444 LoadState Job::GetLoadState() const { |
| 370 CheckIsOnOriginThread(); | 445 CheckIsOnOriginThread(); |
| 371 | 446 |
| 372 if (pending_dns_) | 447 if (pending_dns_) |
| 373 return LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT; | 448 return LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT; |
| 374 | 449 |
| 375 return LOAD_STATE_RESOLVING_PROXY_FOR_URL; | 450 return LOAD_STATE_RESOLVING_PROXY_FOR_URL; |
| 376 } | 451 } |
| 377 | 452 |
| 378 ProxyResolverV8Tracing::Job::~Job() { | 453 Job::~Job() { |
| 379 DCHECK(!pending_dns_); | 454 DCHECK(!pending_dns_); |
| 380 DCHECK(callback_.is_null()); | 455 DCHECK(callback_.is_null()); |
| 381 } | 456 } |
| 382 | 457 |
| 383 void ProxyResolverV8Tracing::Job::CheckIsOnWorkerThread() const { | 458 void Job::CheckIsOnWorkerThread() const { |
| 384 DCHECK_EQ(base::MessageLoop::current(), parent_->thread_->message_loop()); | 459 DCHECK(params_->worker_task_runner->BelongsToCurrentThread()); |
| 385 } | 460 } |
| 386 | 461 |
| 387 void ProxyResolverV8Tracing::Job::CheckIsOnOriginThread() const { | 462 void Job::CheckIsOnOriginThread() const { |
| 388 DCHECK(origin_loop_->BelongsToCurrentThread()); | 463 DCHECK(origin_loop_->BelongsToCurrentThread()); |
| 389 } | 464 } |
| 390 | 465 |
| 391 void ProxyResolverV8Tracing::Job::SetCallback( | 466 void Job::SetCallback(const CompletionCallback& callback) { |
| 392 const CompletionCallback& callback) { | |
| 393 CheckIsOnOriginThread(); | 467 CheckIsOnOriginThread(); |
| 394 DCHECK(callback_.is_null()); | 468 DCHECK(callback_.is_null()); |
| 395 parent_->num_outstanding_callbacks_++; | 469 (*params_->num_outstanding_callbacks)++; |
| 396 callback_ = callback; | 470 callback_ = callback; |
| 397 } | 471 } |
| 398 | 472 |
| 399 void ProxyResolverV8Tracing::Job::ReleaseCallback() { | 473 void Job::ReleaseCallback() { |
| 400 CheckIsOnOriginThread(); | 474 CheckIsOnOriginThread(); |
| 401 DCHECK(!callback_.is_null()); | 475 DCHECK(!callback_.is_null()); |
| 402 CHECK_GT(parent_->num_outstanding_callbacks_, 0); | 476 CHECK_GT(*params_->num_outstanding_callbacks, 0); |
| 403 parent_->num_outstanding_callbacks_--; | 477 (*params_->num_outstanding_callbacks)--; |
| 404 callback_.Reset(); | 478 callback_.Reset(); |
| 405 | 479 |
| 406 // For good measure, clear this other user-owned pointer. | 480 // For good measure, clear this other user-owned pointer. |
| 407 user_results_ = NULL; | 481 user_results_ = NULL; |
| 408 } | 482 } |
| 409 | 483 |
| 410 ProxyResolverV8* ProxyResolverV8Tracing::Job::v8_resolver() { | 484 ProxyResolverV8* Job::v8_resolver() { |
| 411 return parent_->v8_resolver_.get(); | 485 return params_->v8_resolver; |
| 412 } | 486 } |
| 413 | 487 |
| 414 base::MessageLoop* ProxyResolverV8Tracing::Job::worker_loop() { | 488 const scoped_refptr<base::SingleThreadTaskRunner>& Job::worker_task_runner() { |
| 415 return parent_->thread_->message_loop(); | 489 return params_->worker_task_runner; |
| 416 } | 490 } |
| 417 | 491 |
| 418 HostResolver* ProxyResolverV8Tracing::Job::host_resolver() { | 492 HostResolver* Job::host_resolver() { |
| 419 return parent_->host_resolver_; | 493 return params_->host_resolver; |
| 420 } | 494 } |
| 421 | 495 |
| 422 ProxyResolverErrorObserver* ProxyResolverV8Tracing::Job::error_observer() { | 496 ProxyResolverErrorObserver* Job::error_observer() { |
| 423 return parent_->error_observer_.get(); | 497 return params_->error_observer; |
| 424 } | 498 } |
| 425 | 499 |
| 426 NetLog* ProxyResolverV8Tracing::Job::net_log() { | 500 NetLog* Job::net_log() { |
| 427 return parent_->net_log_; | 501 return params_->net_log; |
| 428 } | 502 } |
| 429 | 503 |
| 430 void ProxyResolverV8Tracing::Job::NotifyCaller(int result) { | 504 void Job::NotifyCaller(int result) { |
| 431 CheckIsOnWorkerThread(); | 505 CheckIsOnWorkerThread(); |
| 432 | 506 |
| 433 origin_loop_->PostTask( | 507 origin_loop_->PostTask( |
| 434 FROM_HERE, | 508 FROM_HERE, |
| 435 base::Bind(&Job::NotifyCallerOnOriginLoop, this, result)); | 509 base::Bind(&Job::NotifyCallerOnOriginLoop, this, result)); |
| 436 } | 510 } |
| 437 | 511 |
| 438 void ProxyResolverV8Tracing::Job::NotifyCallerOnOriginLoop(int result) { | 512 void Job::NotifyCallerOnOriginLoop(int result) { |
| 439 CheckIsOnOriginThread(); | 513 CheckIsOnOriginThread(); |
| 440 | 514 |
| 441 if (cancelled_.IsSet()) | 515 if (cancelled_.IsSet()) |
| 442 return; | 516 return; |
| 443 | 517 |
| 444 DCHECK(!callback_.is_null()); | 518 DCHECK(!callback_.is_null()); |
| 445 DCHECK(!pending_dns_); | 519 DCHECK(!pending_dns_); |
| 446 | 520 |
| 447 if (operation_ == GET_PROXY_FOR_URL) { | 521 if (operation_ == GET_PROXY_FOR_URL) { |
| 448 *user_results_ = results_; | 522 *user_results_ = results_; |
| 449 } | 523 } |
| 450 | 524 |
| 451 // There is only ever 1 outstanding SET_PAC_SCRIPT job. It needs to be | |
| 452 // tracked to support cancellation. | |
| 453 if (operation_ == SET_PAC_SCRIPT) { | |
| 454 DCHECK_EQ(parent_->set_pac_script_job_.get(), this); | |
| 455 parent_->set_pac_script_job_ = NULL; | |
| 456 } | |
| 457 | |
| 458 CompletionCallback callback = callback_; | 525 CompletionCallback callback = callback_; |
| 459 ReleaseCallback(); | 526 ReleaseCallback(); |
| 460 callback.Run(result); | 527 callback.Run(result); |
| 461 | 528 |
| 462 owned_self_reference_ = NULL; | 529 owned_self_reference_ = NULL; |
| 463 } | 530 } |
| 464 | 531 |
| 465 void ProxyResolverV8Tracing::Job::Start(Operation op, bool blocking_dns, | 532 void Job::Start(Operation op, |
| 466 const CompletionCallback& callback) { | 533 bool blocking_dns, |
| 534 const CompletionCallback& callback) { | |
| 467 CheckIsOnOriginThread(); | 535 CheckIsOnOriginThread(); |
| 468 | 536 |
| 469 operation_ = op; | 537 operation_ = op; |
| 470 blocking_dns_ = blocking_dns; | 538 blocking_dns_ = blocking_dns; |
| 471 SetCallback(callback); | 539 SetCallback(callback); |
| 472 | 540 |
| 473 owned_self_reference_ = this; | 541 owned_self_reference_ = this; |
| 474 | 542 |
| 475 worker_loop()->PostTask(FROM_HERE, | 543 worker_task_runner()->PostTask( |
| 476 blocking_dns_ ? base::Bind(&Job::ExecuteBlocking, this) : | 544 FROM_HERE, blocking_dns_ ? base::Bind(&Job::ExecuteBlocking, this) |
| 477 base::Bind(&Job::ExecuteNonBlocking, this)); | 545 : base::Bind(&Job::ExecuteNonBlocking, this)); |
| 478 } | 546 } |
| 479 | 547 |
| 480 void ProxyResolverV8Tracing::Job::ExecuteBlocking() { | 548 void Job::ExecuteBlocking() { |
| 481 CheckIsOnWorkerThread(); | 549 CheckIsOnWorkerThread(); |
| 482 DCHECK(blocking_dns_); | 550 DCHECK(blocking_dns_); |
| 483 | 551 |
| 484 if (cancelled_.IsSet()) | 552 if (cancelled_.IsSet()) |
| 485 return; | 553 return; |
| 486 | 554 |
| 487 NotifyCaller(ExecuteProxyResolver()); | 555 NotifyCaller(ExecuteProxyResolver()); |
| 488 } | 556 } |
| 489 | 557 |
| 490 void ProxyResolverV8Tracing::Job::ExecuteNonBlocking() { | 558 void Job::ExecuteNonBlocking() { |
| 491 CheckIsOnWorkerThread(); | 559 CheckIsOnWorkerThread(); |
| 492 DCHECK(!blocking_dns_); | 560 DCHECK(!blocking_dns_); |
| 493 | 561 |
| 494 if (cancelled_.IsSet()) | 562 if (cancelled_.IsSet()) |
| 495 return; | 563 return; |
| 496 | 564 |
| 497 // Reset state for the current execution. | 565 // Reset state for the current execution. |
| 498 abandoned_ = false; | 566 abandoned_ = false; |
| 499 num_dns_ = 0; | 567 num_dns_ = 0; |
| 500 alerts_and_errors_.clear(); | 568 alerts_and_errors_.clear(); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 511 return; | 579 return; |
| 512 } | 580 } |
| 513 | 581 |
| 514 if (abandoned_) | 582 if (abandoned_) |
| 515 return; | 583 return; |
| 516 | 584 |
| 517 DispatchBufferedAlertsAndErrors(); | 585 DispatchBufferedAlertsAndErrors(); |
| 518 NotifyCaller(result); | 586 NotifyCaller(result); |
| 519 } | 587 } |
| 520 | 588 |
| 521 int ProxyResolverV8Tracing::Job::ExecuteProxyResolver() { | 589 int Job::ExecuteProxyResolver() { |
| 522 JSBindings* prev_bindings = v8_resolver()->js_bindings(); | |
| 523 v8_resolver()->set_js_bindings(this); | |
| 524 | |
| 525 int result = ERR_UNEXPECTED; // Initialized to silence warnings. | 590 int result = ERR_UNEXPECTED; // Initialized to silence warnings. |
| 526 | 591 |
| 527 switch (operation_) { | 592 switch (operation_) { |
| 528 case SET_PAC_SCRIPT: | 593 case CREATE_V8_RESOLVER: { |
| 529 result = v8_resolver()->SetPacScript( | 594 scoped_ptr<ProxyResolverV8> resolver(new ProxyResolverV8); |
| 530 script_data_, CompletionCallback()); | 595 resolver->set_js_bindings(this); |
| 596 result = resolver->SetPacScript(script_data_, CompletionCallback()); | |
| 597 resolver->set_js_bindings(nullptr); | |
| 598 if (result == OK) | |
| 599 *resolver_out_ = resolver.Pass(); | |
| 531 break; | 600 break; |
| 532 case GET_PROXY_FOR_URL: | 601 } |
| 602 case GET_PROXY_FOR_URL: { | |
| 603 JSBindings* prev_bindings = v8_resolver()->js_bindings(); | |
| 604 v8_resolver()->set_js_bindings(this); | |
| 605 | |
| 533 result = v8_resolver()->GetProxyForURL( | 606 result = v8_resolver()->GetProxyForURL( |
| 534 url_, | 607 url_, |
| 535 // Important: Do not write directly into |user_results_|, since if the | 608 // Important: Do not write directly into |user_results_|, since if the |
| 536 // request were to be cancelled from the origin thread, must guarantee | 609 // request were to be cancelled from the origin thread, must guarantee |
| 537 // that |user_results_| is not accessed anymore. | 610 // that |user_results_| is not accessed anymore. |
| 538 &results_, | 611 &results_, |
| 539 CompletionCallback(), | 612 CompletionCallback(), |
| 540 NULL, | 613 NULL, |
| 541 bound_net_log_); | 614 bound_net_log_); |
| 615 v8_resolver()->set_js_bindings(prev_bindings); | |
| 542 break; | 616 break; |
| 617 } | |
| 543 } | 618 } |
| 544 | 619 |
| 545 v8_resolver()->set_js_bindings(prev_bindings); | |
| 546 | |
| 547 return result; | 620 return result; |
| 548 } | 621 } |
| 549 | 622 |
| 550 bool ProxyResolverV8Tracing::Job::ResolveDns(const std::string& host, | 623 bool Job::ResolveDns(const std::string& host, |
| 551 ResolveDnsOperation op, | 624 ResolveDnsOperation op, |
| 552 std::string* output, | 625 std::string* output, |
| 553 bool* terminate) { | 626 bool* terminate) { |
| 554 if (cancelled_.IsSet()) { | 627 if (cancelled_.IsSet()) { |
| 555 *terminate = true; | 628 *terminate = true; |
| 556 return false; | 629 return false; |
| 557 } | 630 } |
| 558 | 631 |
| 559 if ((op == DNS_RESOLVE || op == DNS_RESOLVE_EX) && host.empty()) { | 632 if ((op == DNS_RESOLVE || op == DNS_RESOLVE_EX) && host.empty()) { |
| 560 // a DNS resolve with an empty hostname is considered an error. | 633 // a DNS resolve with an empty hostname is considered an error. |
| 561 return false; | 634 return false; |
| 562 } | 635 } |
| 563 | 636 |
| 564 return blocking_dns_ ? | 637 return blocking_dns_ ? |
| 565 ResolveDnsBlocking(host, op, output) : | 638 ResolveDnsBlocking(host, op, output) : |
| 566 ResolveDnsNonBlocking(host, op, output, terminate); | 639 ResolveDnsNonBlocking(host, op, output, terminate); |
| 567 } | 640 } |
| 568 | 641 |
| 569 void ProxyResolverV8Tracing::Job::Alert(const base::string16& message) { | 642 void Job::Alert(const base::string16& message) { |
| 570 HandleAlertOrError(true, -1, message); | 643 HandleAlertOrError(true, -1, message); |
| 571 } | 644 } |
| 572 | 645 |
| 573 void ProxyResolverV8Tracing::Job::OnError(int line_number, | 646 void Job::OnError(int line_number, const base::string16& error) { |
| 574 const base::string16& error) { | |
| 575 HandleAlertOrError(false, line_number, error); | 647 HandleAlertOrError(false, line_number, error); |
| 576 } | 648 } |
| 577 | 649 |
| 578 bool ProxyResolverV8Tracing::Job::ResolveDnsBlocking(const std::string& host, | 650 bool Job::ResolveDnsBlocking(const std::string& host, |
| 579 ResolveDnsOperation op, | 651 ResolveDnsOperation op, |
| 580 std::string* output) { | 652 std::string* output) { |
| 581 CheckIsOnWorkerThread(); | 653 CheckIsOnWorkerThread(); |
| 582 | 654 |
| 583 // Check if the DNS result for this host has already been cached. | 655 // Check if the DNS result for this host has already been cached. |
| 584 bool rv; | 656 bool rv; |
| 585 if (GetDnsFromLocalCache(host, op, output, &rv)) { | 657 if (GetDnsFromLocalCache(host, op, output, &rv)) { |
| 586 // Yay, cache hit! | 658 // Yay, cache hit! |
| 587 return rv; | 659 return rv; |
| 588 } | 660 } |
| 589 | 661 |
| 590 if (dns_cache_.size() >= kMaxUniqueResolveDnsPerExec) { | 662 if (dns_cache_.size() >= kMaxUniqueResolveDnsPerExec) { |
| 591 // Safety net for scripts with unexpectedly many DNS calls. | 663 // Safety net for scripts with unexpectedly many DNS calls. |
| 592 // We will continue running to completion, but will fail every | 664 // We will continue running to completion, but will fail every |
| 593 // subsequent DNS request. | 665 // subsequent DNS request. |
| 594 return false; | 666 return false; |
| 595 } | 667 } |
| 596 | 668 |
| 597 if (!PostDnsOperationAndWait(host, op, NULL)) | 669 if (!PostDnsOperationAndWait(host, op, NULL)) |
| 598 return false; // Was cancelled. | 670 return false; // Was cancelled. |
| 599 | 671 |
| 600 CHECK(GetDnsFromLocalCache(host, op, output, &rv)); | 672 CHECK(GetDnsFromLocalCache(host, op, output, &rv)); |
| 601 return rv; | 673 return rv; |
| 602 } | 674 } |
| 603 | 675 |
| 604 bool ProxyResolverV8Tracing::Job::ResolveDnsNonBlocking(const std::string& host, | 676 bool Job::ResolveDnsNonBlocking(const std::string& host, |
| 605 ResolveDnsOperation op, | 677 ResolveDnsOperation op, |
| 606 std::string* output, | 678 std::string* output, |
| 607 bool* terminate) { | 679 bool* terminate) { |
| 608 CheckIsOnWorkerThread(); | 680 CheckIsOnWorkerThread(); |
| 609 | 681 |
| 610 if (abandoned_) { | 682 if (abandoned_) { |
| 611 // If this execution was already abandoned can fail right away. Only 1 DNS | 683 // If this execution was already abandoned can fail right away. Only 1 DNS |
| 612 // dependency will be traced at a time (for more predictable outcomes). | 684 // dependency will be traced at a time (for more predictable outcomes). |
| 613 return false; | 685 return false; |
| 614 } | 686 } |
| 615 | 687 |
| 616 num_dns_ += 1; | 688 num_dns_ += 1; |
| 617 | 689 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 647 | 719 |
| 648 // Otherwise if the result was not in the cache, then a DNS request has | 720 // Otherwise if the result was not in the cache, then a DNS request has |
| 649 // been started. Abandon this invocation of FindProxyForURL(), it will be | 721 // been started. Abandon this invocation of FindProxyForURL(), it will be |
| 650 // restarted once the DNS request completes. | 722 // restarted once the DNS request completes. |
| 651 abandoned_ = true; | 723 abandoned_ = true; |
| 652 *terminate = true; | 724 *terminate = true; |
| 653 last_num_dns_ = num_dns_; | 725 last_num_dns_ = num_dns_; |
| 654 return false; | 726 return false; |
| 655 } | 727 } |
| 656 | 728 |
| 657 bool ProxyResolverV8Tracing::Job::PostDnsOperationAndWait( | 729 bool Job::PostDnsOperationAndWait(const std::string& host, |
| 658 const std::string& host, ResolveDnsOperation op, | 730 ResolveDnsOperation op, |
| 659 bool* completed_synchronously) { | 731 bool* completed_synchronously) { |
| 660 | |
| 661 // Post the DNS request to the origin thread. | 732 // Post the DNS request to the origin thread. |
| 662 DCHECK(!pending_dns_); | 733 DCHECK(!pending_dns_); |
| 663 pending_dns_host_ = host; | 734 pending_dns_host_ = host; |
| 664 pending_dns_op_ = op; | 735 pending_dns_op_ = op; |
| 665 origin_loop_->PostTask(FROM_HERE, base::Bind(&Job::DoDnsOperation, this)); | 736 origin_loop_->PostTask(FROM_HERE, base::Bind(&Job::DoDnsOperation, this)); |
| 666 | 737 |
| 667 event_.Wait(); | 738 event_.Wait(); |
| 668 event_.Reset(); | 739 event_.Reset(); |
| 669 | 740 |
| 670 if (cancelled_.IsSet()) | 741 if (cancelled_.IsSet()) |
| 671 return false; | 742 return false; |
| 672 | 743 |
| 673 if (completed_synchronously) | 744 if (completed_synchronously) |
| 674 *completed_synchronously = pending_dns_completed_synchronously_; | 745 *completed_synchronously = pending_dns_completed_synchronously_; |
| 675 | 746 |
| 676 return true; | 747 return true; |
| 677 } | 748 } |
| 678 | 749 |
| 679 void ProxyResolverV8Tracing::Job::DoDnsOperation() { | 750 void Job::DoDnsOperation() { |
| 680 CheckIsOnOriginThread(); | 751 CheckIsOnOriginThread(); |
| 681 DCHECK(!pending_dns_); | 752 DCHECK(!pending_dns_); |
| 682 | 753 |
| 683 if (cancelled_.IsSet()) | 754 if (cancelled_.IsSet()) |
| 684 return; | 755 return; |
| 685 | 756 |
| 686 HostResolver::RequestHandle dns_request = NULL; | 757 HostResolver::RequestHandle dns_request = NULL; |
| 687 int result = host_resolver()->Resolve( | 758 int result = host_resolver()->Resolve( |
| 688 MakeDnsRequestInfo(pending_dns_host_, pending_dns_op_), | 759 MakeDnsRequestInfo(pending_dns_host_, pending_dns_op_), |
| 689 DEFAULT_PRIORITY, | 760 DEFAULT_PRIORITY, |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 701 if (!pending_dns_completed_synchronously_) | 772 if (!pending_dns_completed_synchronously_) |
| 702 host_resolver()->CancelRequest(dns_request); | 773 host_resolver()->CancelRequest(dns_request); |
| 703 return; | 774 return; |
| 704 } | 775 } |
| 705 | 776 |
| 706 if (pending_dns_completed_synchronously_) { | 777 if (pending_dns_completed_synchronously_) { |
| 707 OnDnsOperationComplete(result); | 778 OnDnsOperationComplete(result); |
| 708 } else { | 779 } else { |
| 709 DCHECK(dns_request); | 780 DCHECK(dns_request); |
| 710 pending_dns_ = dns_request; | 781 pending_dns_ = dns_request; |
| 711 if (!parent_->on_load_state_changed_.is_null()) { | 782 if (!params_->on_load_state_changed.is_null()) { |
| 712 parent_->on_load_state_changed_.Run( | 783 params_->on_load_state_changed.Run( |
| 713 this, LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT); | 784 this, LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT); |
| 714 } | 785 } |
| 715 // OnDnsOperationComplete() will be called by host resolver on completion. | 786 // OnDnsOperationComplete() will be called by host resolver on completion. |
| 716 } | 787 } |
| 717 | 788 |
| 718 if (!blocking_dns_) { | 789 if (!blocking_dns_) { |
| 719 // The worker thread always blocks waiting to see if the result can be | 790 // The worker thread always blocks waiting to see if the result can be |
| 720 // serviced from cache before restarting. | 791 // serviced from cache before restarting. |
| 721 event_.Signal(); | 792 event_.Signal(); |
| 722 } | 793 } |
| 723 } | 794 } |
| 724 | 795 |
| 725 void ProxyResolverV8Tracing::Job::OnDnsOperationComplete(int result) { | 796 void Job::OnDnsOperationComplete(int result) { |
| 726 CheckIsOnOriginThread(); | 797 CheckIsOnOriginThread(); |
| 727 | 798 |
| 728 DCHECK(!cancelled_.IsSet()); | 799 DCHECK(!cancelled_.IsSet()); |
| 729 DCHECK(pending_dns_completed_synchronously_ == (pending_dns_ == NULL)); | 800 DCHECK(pending_dns_completed_synchronously_ == (pending_dns_ == NULL)); |
| 730 | 801 |
| 731 SaveDnsToLocalCache(pending_dns_host_, pending_dns_op_, result, | 802 SaveDnsToLocalCache(pending_dns_host_, pending_dns_op_, result, |
| 732 pending_dns_addresses_); | 803 pending_dns_addresses_); |
| 733 pending_dns_ = NULL; | 804 pending_dns_ = NULL; |
| 734 | 805 |
| 735 if (!parent_->on_load_state_changed_.is_null() && | 806 if (!params_->on_load_state_changed.is_null() && |
| 736 !pending_dns_completed_synchronously_ && !cancelled_.IsSet()) { | 807 !pending_dns_completed_synchronously_ && !cancelled_.IsSet()) { |
| 737 parent_->on_load_state_changed_.Run(this, | 808 params_->on_load_state_changed.Run(this, |
| 738 LOAD_STATE_RESOLVING_PROXY_FOR_URL); | 809 LOAD_STATE_RESOLVING_PROXY_FOR_URL); |
| 739 } | 810 } |
| 740 | 811 |
| 741 if (blocking_dns_) { | 812 if (blocking_dns_) { |
| 742 event_.Signal(); | 813 event_.Signal(); |
| 743 return; | 814 return; |
| 744 } | 815 } |
| 745 | 816 |
| 746 if (!blocking_dns_ && !pending_dns_completed_synchronously_) { | 817 if (!blocking_dns_ && !pending_dns_completed_synchronously_) { |
| 747 // Restart. This time it should make more progress due to having | 818 // Restart. This time it should make more progress due to having |
| 748 // cached items. | 819 // cached items. |
| 749 worker_loop()->PostTask(FROM_HERE, | 820 worker_task_runner()->PostTask(FROM_HERE, |
| 750 base::Bind(&Job::ExecuteNonBlocking, this)); | 821 base::Bind(&Job::ExecuteNonBlocking, this)); |
| 751 } | 822 } |
| 752 } | 823 } |
| 753 | 824 |
| 754 void ProxyResolverV8Tracing::Job::ScheduleRestartWithBlockingDns() { | 825 void Job::ScheduleRestartWithBlockingDns() { |
| 755 CheckIsOnWorkerThread(); | 826 CheckIsOnWorkerThread(); |
| 756 | 827 |
| 757 DCHECK(!should_restart_with_blocking_dns_); | 828 DCHECK(!should_restart_with_blocking_dns_); |
| 758 DCHECK(!abandoned_); | 829 DCHECK(!abandoned_); |
| 759 DCHECK(!blocking_dns_); | 830 DCHECK(!blocking_dns_); |
| 760 | 831 |
| 761 abandoned_ = true; | 832 abandoned_ = true; |
| 762 | 833 |
| 763 // The restart will happen after ExecuteNonBlocking() finishes. | 834 // The restart will happen after ExecuteNonBlocking() finishes. |
| 764 should_restart_with_blocking_dns_ = true; | 835 should_restart_with_blocking_dns_ = true; |
| 765 } | 836 } |
| 766 | 837 |
| 767 bool ProxyResolverV8Tracing::Job::GetDnsFromLocalCache( | 838 bool Job::GetDnsFromLocalCache(const std::string& host, |
| 768 const std::string& host, | 839 ResolveDnsOperation op, |
| 769 ResolveDnsOperation op, | 840 std::string* output, |
| 770 std::string* output, | 841 bool* return_value) { |
| 771 bool* return_value) { | |
| 772 CheckIsOnWorkerThread(); | 842 CheckIsOnWorkerThread(); |
| 773 | 843 |
| 774 DnsCache::const_iterator it = dns_cache_.find(MakeDnsCacheKey(host, op)); | 844 DnsCache::const_iterator it = dns_cache_.find(MakeDnsCacheKey(host, op)); |
| 775 if (it == dns_cache_.end()) | 845 if (it == dns_cache_.end()) |
| 776 return false; | 846 return false; |
| 777 | 847 |
| 778 *output = it->second; | 848 *output = it->second; |
| 779 *return_value = !it->second.empty(); | 849 *return_value = !it->second.empty(); |
| 780 return true; | 850 return true; |
| 781 } | 851 } |
| 782 | 852 |
| 783 void ProxyResolverV8Tracing::Job::SaveDnsToLocalCache( | 853 void Job::SaveDnsToLocalCache(const std::string& host, |
| 784 const std::string& host, | 854 ResolveDnsOperation op, |
| 785 ResolveDnsOperation op, | 855 int net_error, |
| 786 int net_error, | 856 const AddressList& addresses) { |
| 787 const AddressList& addresses) { | |
| 788 CheckIsOnOriginThread(); | 857 CheckIsOnOriginThread(); |
| 789 | 858 |
| 790 // Serialize the result into a string to save to the cache. | 859 // Serialize the result into a string to save to the cache. |
| 791 std::string cache_value; | 860 std::string cache_value; |
| 792 if (net_error != OK) { | 861 if (net_error != OK) { |
| 793 cache_value = std::string(); | 862 cache_value = std::string(); |
| 794 } else if (op == DNS_RESOLVE || op == MY_IP_ADDRESS) { | 863 } else if (op == DNS_RESOLVE || op == MY_IP_ADDRESS) { |
| 795 // dnsResolve() and myIpAddress() are expected to return a single IP | 864 // dnsResolve() and myIpAddress() are expected to return a single IP |
| 796 // address. | 865 // address. |
| 797 cache_value = addresses.front().ToStringWithoutPort(); | 866 cache_value = addresses.front().ToStringWithoutPort(); |
| 798 } else { | 867 } else { |
| 799 // The *Ex versions are expected to return a semi-colon separated list. | 868 // The *Ex versions are expected to return a semi-colon separated list. |
| 800 for (AddressList::const_iterator iter = addresses.begin(); | 869 for (AddressList::const_iterator iter = addresses.begin(); |
| 801 iter != addresses.end(); ++iter) { | 870 iter != addresses.end(); ++iter) { |
| 802 if (!cache_value.empty()) | 871 if (!cache_value.empty()) |
| 803 cache_value += ";"; | 872 cache_value += ";"; |
| 804 cache_value += iter->ToStringWithoutPort(); | 873 cache_value += iter->ToStringWithoutPort(); |
| 805 } | 874 } |
| 806 } | 875 } |
| 807 | 876 |
| 808 dns_cache_[MakeDnsCacheKey(host, op)] = cache_value; | 877 dns_cache_[MakeDnsCacheKey(host, op)] = cache_value; |
| 809 } | 878 } |
| 810 | 879 |
| 811 // static | 880 // static |
| 812 HostResolver::RequestInfo ProxyResolverV8Tracing::Job::MakeDnsRequestInfo( | 881 HostResolver::RequestInfo Job::MakeDnsRequestInfo(const std::string& host, |
| 813 const std::string& host, ResolveDnsOperation op) { | 882 ResolveDnsOperation op) { |
| 814 HostPortPair host_port = HostPortPair(host, 80); | 883 HostPortPair host_port = HostPortPair(host, 80); |
| 815 if (op == MY_IP_ADDRESS || op == MY_IP_ADDRESS_EX) { | 884 if (op == MY_IP_ADDRESS || op == MY_IP_ADDRESS_EX) { |
| 816 host_port.set_host(GetHostName()); | 885 host_port.set_host(GetHostName()); |
| 817 } | 886 } |
| 818 | 887 |
| 819 HostResolver::RequestInfo info(host_port); | 888 HostResolver::RequestInfo info(host_port); |
| 820 // Flag myIpAddress requests. | 889 // Flag myIpAddress requests. |
| 821 if (op == MY_IP_ADDRESS || op == MY_IP_ADDRESS_EX) { | 890 if (op == MY_IP_ADDRESS || op == MY_IP_ADDRESS_EX) { |
| 822 // TODO: Provide a RequestInfo construction mechanism that does not | 891 // TODO: Provide a RequestInfo construction mechanism that does not |
| 823 // require a hostname and sets is_my_ip_address to true instead of this. | 892 // require a hostname and sets is_my_ip_address to true instead of this. |
| 824 info.set_is_my_ip_address(true); | 893 info.set_is_my_ip_address(true); |
| 825 } | 894 } |
| 826 // The non-ex flavors are limited to IPv4 results. | 895 // The non-ex flavors are limited to IPv4 results. |
| 827 if (op == MY_IP_ADDRESS || op == DNS_RESOLVE) { | 896 if (op == MY_IP_ADDRESS || op == DNS_RESOLVE) { |
| 828 info.set_address_family(ADDRESS_FAMILY_IPV4); | 897 info.set_address_family(ADDRESS_FAMILY_IPV4); |
| 829 } | 898 } |
| 830 | 899 |
| 831 return info; | 900 return info; |
| 832 } | 901 } |
| 833 | 902 |
| 834 std::string ProxyResolverV8Tracing::Job::MakeDnsCacheKey( | 903 std::string Job::MakeDnsCacheKey(const std::string& host, |
| 835 const std::string& host, ResolveDnsOperation op) { | 904 ResolveDnsOperation op) { |
| 836 return base::StringPrintf("%d:%s", op, host.c_str()); | 905 return base::StringPrintf("%d:%s", op, host.c_str()); |
| 837 } | 906 } |
| 838 | 907 |
| 839 void ProxyResolverV8Tracing::Job::HandleAlertOrError( | 908 void Job::HandleAlertOrError(bool is_alert, |
| 840 bool is_alert, | 909 int line_number, |
| 841 int line_number, | 910 const base::string16& message) { |
| 842 const base::string16& message) { | |
| 843 CheckIsOnWorkerThread(); | 911 CheckIsOnWorkerThread(); |
| 844 | 912 |
| 845 if (cancelled_.IsSet()) | 913 if (cancelled_.IsSet()) |
| 846 return; | 914 return; |
| 847 | 915 |
| 848 if (blocking_dns_) { | 916 if (blocking_dns_) { |
| 849 // In blocking DNS mode the events can be dispatched immediately. | 917 // In blocking DNS mode the events can be dispatched immediately. |
| 850 DispatchAlertOrError(is_alert, line_number, message); | 918 DispatchAlertOrError(is_alert, line_number, message); |
| 851 return; | 919 return; |
| 852 } | 920 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 864 // Avoid this by falling back to blocking mode. | 932 // Avoid this by falling back to blocking mode. |
| 865 if (alerts_and_errors_byte_cost_ > kMaxAlertsAndErrorsBytes) { | 933 if (alerts_and_errors_byte_cost_ > kMaxAlertsAndErrorsBytes) { |
| 866 ScheduleRestartWithBlockingDns(); | 934 ScheduleRestartWithBlockingDns(); |
| 867 return; | 935 return; |
| 868 } | 936 } |
| 869 | 937 |
| 870 AlertOrError entry = {is_alert, line_number, message}; | 938 AlertOrError entry = {is_alert, line_number, message}; |
| 871 alerts_and_errors_.push_back(entry); | 939 alerts_and_errors_.push_back(entry); |
| 872 } | 940 } |
| 873 | 941 |
| 874 void ProxyResolverV8Tracing::Job::DispatchBufferedAlertsAndErrors() { | 942 void Job::DispatchBufferedAlertsAndErrors() { |
| 875 CheckIsOnWorkerThread(); | 943 CheckIsOnWorkerThread(); |
| 876 DCHECK(!blocking_dns_); | 944 DCHECK(!blocking_dns_); |
| 877 DCHECK(!abandoned_); | 945 DCHECK(!abandoned_); |
| 878 | 946 |
| 879 for (size_t i = 0; i < alerts_and_errors_.size(); ++i) { | 947 for (size_t i = 0; i < alerts_and_errors_.size(); ++i) { |
| 880 const AlertOrError& x = alerts_and_errors_[i]; | 948 const AlertOrError& x = alerts_and_errors_[i]; |
| 881 DispatchAlertOrError(x.is_alert, x.line_number, x.message); | 949 DispatchAlertOrError(x.is_alert, x.line_number, x.message); |
| 882 } | 950 } |
| 883 } | 951 } |
| 884 | 952 |
| 885 void ProxyResolverV8Tracing::Job::DispatchAlertOrError( | 953 void Job::DispatchAlertOrError(bool is_alert, |
| 886 bool is_alert, int line_number, const base::string16& message) { | 954 int line_number, |
| 955 const base::string16& message) { | |
| 887 CheckIsOnWorkerThread(); | 956 CheckIsOnWorkerThread(); |
| 888 | 957 |
| 889 // Note that the handling of cancellation is racy with regard to | 958 // Note that the handling of cancellation is racy with regard to |
| 890 // alerts/errors. The request might get cancelled shortly after this | 959 // alerts/errors. The request might get cancelled shortly after this |
| 891 // check! (There is no lock being held to guarantee otherwise). | 960 // check! (There is no lock being held to guarantee otherwise). |
| 892 // | 961 // |
| 893 // If this happens, then some information will get written to the NetLog | 962 // If this happens, then some information will get written to the NetLog |
| 894 // needlessly, however the NetLog will still be alive so it shouldn't cause | 963 // needlessly, however the NetLog will still be alive so it shouldn't cause |
| 895 // problems. | 964 // problems. |
| 896 if (cancelled_.IsSet()) | 965 if (cancelled_.IsSet()) |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 918 // Send the error to the NetLog. | 987 // Send the error to the NetLog. |
| 919 LogEventToCurrentRequestAndGlobally( | 988 LogEventToCurrentRequestAndGlobally( |
| 920 NetLog::TYPE_PAC_JAVASCRIPT_ERROR, | 989 NetLog::TYPE_PAC_JAVASCRIPT_ERROR, |
| 921 base::Bind(&NetLogErrorCallback, line_number, &message)); | 990 base::Bind(&NetLogErrorCallback, line_number, &message)); |
| 922 | 991 |
| 923 if (error_observer()) | 992 if (error_observer()) |
| 924 error_observer()->OnPACScriptError(line_number, message); | 993 error_observer()->OnPACScriptError(line_number, message); |
| 925 } | 994 } |
| 926 } | 995 } |
| 927 | 996 |
| 928 void ProxyResolverV8Tracing::Job::LogEventToCurrentRequestAndGlobally( | 997 void Job::LogEventToCurrentRequestAndGlobally( |
| 929 NetLog::EventType type, | 998 NetLog::EventType type, |
| 930 const NetLog::ParametersCallback& parameters_callback) { | 999 const NetLog::ParametersCallback& parameters_callback) { |
| 931 CheckIsOnWorkerThread(); | 1000 CheckIsOnWorkerThread(); |
| 932 bound_net_log_.AddEvent(type, parameters_callback); | 1001 bound_net_log_.AddEvent(type, parameters_callback); |
| 933 | 1002 |
| 934 // Emit to the global NetLog event stream. | 1003 // Emit to the global NetLog event stream. |
| 935 if (net_log()) | 1004 if (net_log()) |
| 936 net_log()->AddGlobalEntry(type, parameters_callback); | 1005 net_log()->AddGlobalEntry(type, parameters_callback); |
| 937 } | 1006 } |
| 938 | 1007 |
| 939 ProxyResolverV8Tracing::ProxyResolverV8Tracing( | 1008 ProxyResolverV8Tracing::ProxyResolverV8Tracing( |
| 940 HostResolver* host_resolver, | 1009 scoped_ptr<ProxyResolverErrorObserver> error_observer, |
| 941 ProxyResolverErrorObserver* error_observer, | 1010 scoped_ptr<base::Thread> thread, |
| 942 NetLog* net_log) | 1011 scoped_ptr<ProxyResolverV8> resolver, |
| 943 : ProxyResolverV8Tracing(host_resolver, | 1012 scoped_ptr<Job::Params> job_params) |
| 944 error_observer, | |
| 945 net_log, | |
| 946 LoadStateChangedCallback()) { | |
| 947 } | |
| 948 | |
| 949 ProxyResolverV8Tracing::ProxyResolverV8Tracing( | |
| 950 HostResolver* host_resolver, | |
| 951 ProxyResolverErrorObserver* error_observer, | |
| 952 NetLog* net_log, | |
| 953 const LoadStateChangedCallback& on_load_state_changed) | |
| 954 : ProxyResolver(true /*expects_pac_bytes*/), | 1013 : ProxyResolver(true /*expects_pac_bytes*/), |
| 955 host_resolver_(host_resolver), | 1014 thread_(thread.Pass()), |
| 956 error_observer_(error_observer), | 1015 v8_resolver_(resolver.Pass()), |
| 957 net_log_(net_log), | 1016 error_observer_(error_observer.Pass()), |
| 958 num_outstanding_callbacks_(0), | 1017 job_params_(job_params.Pass()), |
| 959 on_load_state_changed_(on_load_state_changed) { | 1018 num_outstanding_callbacks_(0) { |
| 960 DCHECK(host_resolver); | 1019 job_params_->num_outstanding_callbacks = &num_outstanding_callbacks_; |
| 961 // Start up the thread. | |
| 962 thread_.reset(new base::Thread("Proxy resolver")); | |
| 963 base::Thread::Options options; | |
| 964 options.timer_slack = base::TIMER_SLACK_MAXIMUM; | |
| 965 CHECK(thread_->StartWithOptions(options)); | |
| 966 | |
| 967 v8_resolver_.reset(new ProxyResolverV8); | |
| 968 } | 1020 } |
| 969 | 1021 |
| 970 ProxyResolverV8Tracing::~ProxyResolverV8Tracing() { | 1022 ProxyResolverV8Tracing::~ProxyResolverV8Tracing() { |
| 971 // Note, all requests should have been cancelled. | 1023 // Note, all requests should have been cancelled. |
| 972 CHECK(!set_pac_script_job_.get()); | |
| 973 CHECK_EQ(0, num_outstanding_callbacks_); | 1024 CHECK_EQ(0, num_outstanding_callbacks_); |
| 974 | 1025 |
| 975 // Join the worker thread. See http://crbug.com/69710. Note that we call | 1026 // Join the worker thread. See http://crbug.com/69710. |
| 976 // Stop() here instead of simply clearing thread_ since there may be pending | |
| 977 // callbacks on the worker thread which want to dereference thread_. | |
| 978 base::ThreadRestrictions::ScopedAllowIO allow_io; | 1027 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 979 thread_->Stop(); | 1028 thread_.reset(); |
| 980 } | 1029 } |
| 981 | 1030 |
| 982 int ProxyResolverV8Tracing::GetProxyForURL(const GURL& url, | 1031 int ProxyResolverV8Tracing::GetProxyForURL(const GURL& url, |
| 983 ProxyInfo* results, | 1032 ProxyInfo* results, |
| 984 const CompletionCallback& callback, | 1033 const CompletionCallback& callback, |
| 985 RequestHandle* request, | 1034 RequestHandle* request, |
| 986 const BoundNetLog& net_log) { | 1035 const BoundNetLog& net_log) { |
| 987 DCHECK(CalledOnValidThread()); | 1036 DCHECK(CalledOnValidThread()); |
| 988 DCHECK(!callback.is_null()); | 1037 DCHECK(!callback.is_null()); |
| 989 DCHECK(!set_pac_script_job_.get()); | |
| 990 | 1038 |
| 991 scoped_refptr<Job> job = new Job(this); | 1039 scoped_refptr<Job> job = new Job(job_params_.get()); |
| 992 | 1040 |
| 993 if (request) | 1041 if (request) |
| 994 *request = job.get(); | 1042 *request = job.get(); |
| 995 | 1043 |
| 996 job->StartGetProxyForURL(url, results, net_log, callback); | 1044 job->StartGetProxyForURL(url, results, net_log, callback); |
| 997 return ERR_IO_PENDING; | 1045 return ERR_IO_PENDING; |
| 998 } | 1046 } |
| 999 | 1047 |
| 1000 void ProxyResolverV8Tracing::CancelRequest(RequestHandle request) { | 1048 void ProxyResolverV8Tracing::CancelRequest(RequestHandle request) { |
| 1001 Job* job = reinterpret_cast<Job*>(request); | 1049 Job* job = reinterpret_cast<Job*>(request); |
| 1002 job->Cancel(); | 1050 job->Cancel(); |
| 1003 } | 1051 } |
| 1004 | 1052 |
| 1005 LoadState ProxyResolverV8Tracing::GetLoadState(RequestHandle request) const { | 1053 LoadState ProxyResolverV8Tracing::GetLoadState(RequestHandle request) const { |
| 1006 Job* job = reinterpret_cast<Job*>(request); | 1054 Job* job = reinterpret_cast<Job*>(request); |
| 1007 return job->GetLoadState(); | 1055 return job->GetLoadState(); |
| 1008 } | 1056 } |
| 1009 | 1057 |
| 1010 void ProxyResolverV8Tracing::CancelSetPacScript() { | 1058 void ProxyResolverV8Tracing::CancelSetPacScript() { |
| 1011 DCHECK(set_pac_script_job_.get()); | 1059 NOTREACHED(); |
| 1012 set_pac_script_job_->Cancel(); | |
| 1013 set_pac_script_job_ = NULL; | |
| 1014 } | 1060 } |
| 1015 | 1061 |
| 1016 int ProxyResolverV8Tracing::SetPacScript( | 1062 int ProxyResolverV8Tracing::SetPacScript( |
| 1017 const scoped_refptr<ProxyResolverScriptData>& script_data, | 1063 const scoped_refptr<ProxyResolverScriptData>& script_data, |
| 1018 const CompletionCallback& callback) { | 1064 const CompletionCallback& callback) { |
| 1019 DCHECK(CalledOnValidThread()); | 1065 NOTREACHED(); |
| 1020 DCHECK(!callback.is_null()); | 1066 return ERR_NOT_IMPLEMENTED; |
| 1067 } | |
| 1021 | 1068 |
| 1022 // Note that there should not be any outstanding (non-cancelled) Jobs when | 1069 } // namespace |
| 1023 // setting the PAC script (ProxyService should guarantee this). If there are, | |
| 1024 // then they might complete in strange ways after the new script is set. | |
| 1025 DCHECK(!set_pac_script_job_.get()); | |
| 1026 CHECK_EQ(0, num_outstanding_callbacks_); | |
| 1027 | 1070 |
| 1028 set_pac_script_job_ = new Job(this); | 1071 class ProxyResolverFactoryV8Tracing::CreateJob |
| 1029 set_pac_script_job_->StartSetPacScript(script_data, callback); | 1072 : public ProxyResolverFactory::Request { |
| 1073 public: | |
| 1074 CreateJob(ProxyResolverFactoryV8Tracing* factory, | |
| 1075 HostResolver* host_resolver, | |
| 1076 scoped_ptr<ProxyResolverErrorObserver> error_observer, | |
| 1077 NetLog* net_log, | |
| 1078 const ProxyResolver::LoadStateChangedCallback& | |
| 1079 load_state_changed_callback, | |
| 1080 const scoped_refptr<ProxyResolverScriptData>& pac_script, | |
| 1081 scoped_ptr<ProxyResolver>* resolver_out, | |
| 1082 const CompletionCallback& callback) | |
| 1083 : factory_(factory), | |
| 1084 thread_(new base::Thread("Proxy Resolver")), | |
| 1085 error_observer_(error_observer.Pass()), | |
| 1086 resolver_out_(resolver_out), | |
| 1087 callback_(callback), | |
| 1088 num_outstanding_callbacks_(0) { | |
| 1089 // Start up the thread. | |
| 1090 base::Thread::Options options; | |
| 1091 options.timer_slack = base::TIMER_SLACK_MAXIMUM; | |
| 1092 CHECK(thread_->StartWithOptions(options)); | |
| 1093 job_params_.reset(new Job::Params( | |
| 1094 thread_->task_runner(), host_resolver, error_observer_.get(), net_log, | |
| 1095 load_state_changed_callback, &num_outstanding_callbacks_)); | |
| 1096 create_resolver_job_ = new Job(job_params_.get()); | |
| 1097 create_resolver_job_->StartCreateV8Resolver( | |
| 1098 pac_script, &v8_resolver_, | |
| 1099 base::Bind( | |
| 1100 &ProxyResolverFactoryV8Tracing::CreateJob::OnV8ResolverCreated, | |
| 1101 base::Unretained(this))); | |
| 1102 } | |
| 1030 | 1103 |
| 1104 ~CreateJob() override { | |
| 1105 if (factory_) { | |
| 1106 factory_->RemoveJob(this); | |
| 1107 DCHECK(create_resolver_job_); | |
| 1108 create_resolver_job_->Cancel(); | |
| 1109 StopWorkerThread(); | |
| 1110 } | |
| 1111 DCHECK_EQ(0, num_outstanding_callbacks_); | |
| 1112 } | |
| 1113 | |
| 1114 void FactoryDestroyed() { | |
| 1115 factory_ = nullptr; | |
| 1116 create_resolver_job_->Cancel(); | |
| 1117 create_resolver_job_ = nullptr; | |
| 1118 StopWorkerThread(); | |
| 1119 } | |
| 1120 | |
| 1121 private: | |
| 1122 void OnV8ResolverCreated(int error) { | |
| 1123 DCHECK(factory_); | |
| 1124 if (error == OK) { | |
| 1125 job_params_->v8_resolver = v8_resolver_.get(); | |
| 1126 resolver_out_->reset( | |
| 1127 new ProxyResolverV8Tracing(error_observer_.Pass(), thread_.Pass(), | |
| 1128 v8_resolver_.Pass(), job_params_.Pass())); | |
| 1129 } else { | |
| 1130 StopWorkerThread(); | |
| 1131 } | |
| 1132 | |
| 1133 factory_->RemoveJob(this); | |
| 1134 factory_ = nullptr; | |
| 1135 create_resolver_job_ = nullptr; | |
| 1136 callback_.Run(error); | |
| 1137 } | |
| 1138 | |
| 1139 void StopWorkerThread() { | |
| 1140 // Join the worker thread. See http://crbug.com/69710. | |
| 1141 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
| 1142 thread_.reset(); | |
| 1143 } | |
| 1144 | |
| 1145 ProxyResolverFactoryV8Tracing* factory_; | |
| 1146 scoped_ptr<base::Thread> thread_; | |
| 1147 scoped_ptr<ProxyResolverErrorObserver> error_observer_; | |
| 1148 scoped_ptr<Job::Params> job_params_; | |
| 1149 scoped_refptr<Job> create_resolver_job_; | |
| 1150 scoped_ptr<ProxyResolverV8> v8_resolver_; | |
| 1151 scoped_ptr<ProxyResolver>* resolver_out_; | |
| 1152 const CompletionCallback callback_; | |
| 1153 int num_outstanding_callbacks_; | |
| 1154 | |
| 1155 DISALLOW_COPY_AND_ASSIGN(CreateJob); | |
| 1156 }; | |
| 1157 | |
| 1158 ProxyResolverFactoryV8Tracing::ProxyResolverFactoryV8Tracing( | |
| 1159 HostResolver* host_resolver, | |
| 1160 NetLog* net_log, | |
| 1161 const ProxyResolver::LoadStateChangedCallback& callback) | |
| 1162 : ProxyResolverFactory(true), | |
| 1163 host_resolver_(host_resolver), | |
| 1164 net_log_(net_log), | |
| 1165 load_state_changed_callback_(callback) { | |
| 1166 } | |
| 1167 | |
| 1168 ProxyResolverFactoryV8Tracing::~ProxyResolverFactoryV8Tracing() { | |
| 1169 for (auto job : jobs_) { | |
| 1170 job->FactoryDestroyed(); | |
| 1171 } | |
| 1172 } | |
| 1173 | |
| 1174 // ProxyResolverFactory override. | |
| 1175 int ProxyResolverFactoryV8Tracing::CreateProxyResolver( | |
| 1176 const scoped_refptr<ProxyResolverScriptData>& pac_script, | |
| 1177 scoped_ptr<ProxyResolver>* resolver, | |
| 1178 const CompletionCallback& callback, | |
| 1179 scoped_ptr<Request>* request) { | |
| 1180 scoped_ptr<CreateJob> job(new CreateJob( | |
| 1181 this, host_resolver_, CreateErrorObserver(), net_log_, | |
| 1182 load_state_changed_callback_, pac_script, resolver, callback)); | |
| 1183 jobs_.insert(job.get()); | |
| 1184 *request = job.Pass(); | |
| 1031 return ERR_IO_PENDING; | 1185 return ERR_IO_PENDING; |
| 1032 } | 1186 } |
| 1033 | 1187 |
| 1188 void ProxyResolverFactoryV8Tracing::RemoveJob( | |
| 1189 ProxyResolverFactoryV8Tracing::CreateJob* job) { | |
| 1190 size_t erased = jobs_.erase(job); | |
| 1191 DCHECK_EQ(1u, erased); | |
| 1192 } | |
| 1193 | |
| 1034 } // namespace net | 1194 } // namespace net |
| OLD | NEW |