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

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

Powered by Google App Engine
This is Rietveld 408576698