Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(765)

Side by Side Diff: net/proxy/proxy_resolver_v8_tracing.cc

Issue 1126513002: Add ProxyResolverFactoryV8Tracing. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mojo-proxy-refactor
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698