| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/proxy/proxy_resolver_v8_tracing.h" | 5 #include "net/proxy/proxy_resolver_v8_tracing.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/message_loop/message_loop_proxy.h" | 8 #include "base/message_loop/message_loop_proxy.h" |
| 9 #include "base/metrics/histogram.h" | |
| 10 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
| 11 #include "base/synchronization/cancellation_flag.h" | 10 #include "base/synchronization/cancellation_flag.h" |
| 12 #include "base/synchronization/waitable_event.h" | 11 #include "base/synchronization/waitable_event.h" |
| 13 #include "base/threading/thread.h" | 12 #include "base/threading/thread.h" |
| 14 #include "base/threading/thread_restrictions.h" | 13 #include "base/threading/thread_restrictions.h" |
| 15 #include "base/values.h" | 14 #include "base/values.h" |
| 16 #include "net/base/address_list.h" | 15 #include "net/base/address_list.h" |
| 17 #include "net/base/net_errors.h" | 16 #include "net/base/net_errors.h" |
| 18 #include "net/base/net_log.h" | 17 #include "net/base/net_log.h" |
| 19 #include "net/dns/host_resolver.h" | 18 #include "net/dns/host_resolver.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 // Returns event parameters for a PAC error message (line number + message). | 56 // Returns event parameters for a PAC error message (line number + message). |
| 58 base::Value* NetLogErrorCallback(int line_number, | 57 base::Value* NetLogErrorCallback(int line_number, |
| 59 const base::string16* message, | 58 const base::string16* message, |
| 60 NetLog::LogLevel /* log_level */) { | 59 NetLog::LogLevel /* log_level */) { |
| 61 base::DictionaryValue* dict = new base::DictionaryValue(); | 60 base::DictionaryValue* dict = new base::DictionaryValue(); |
| 62 dict->SetInteger("line_number", line_number); | 61 dict->SetInteger("line_number", line_number); |
| 63 dict->SetString("message", *message); | 62 dict->SetString("message", *message); |
| 64 return dict; | 63 return dict; |
| 65 } | 64 } |
| 66 | 65 |
| 67 void IncrementWithoutOverflow(uint8* x) { | |
| 68 if (*x != 0xFF) | |
| 69 *x += 1; | |
| 70 } | |
| 71 | |
| 72 } // namespace | 66 } // namespace |
| 73 | 67 |
| 74 // The Job class is responsible for executing GetProxyForURL() and | 68 // The Job class is responsible for executing GetProxyForURL() and |
| 75 // SetPacScript(), since both of these operations share similar code. | 69 // SetPacScript(), since both of these operations share similar code. |
| 76 // | 70 // |
| 77 // The DNS for these operations can operate in either blocking or | 71 // The DNS for these operations can operate in either blocking or |
| 78 // non-blocking mode. Blocking mode is used as a fallback when the PAC script | 72 // non-blocking mode. Blocking mode is used as a fallback when the PAC script |
| 79 // seems to be misbehaving under the tracing optimization. | 73 // seems to be misbehaving under the tracing optimization. |
| 80 // | 74 // |
| 81 // Note that this class runs on both the origin thread and a worker | 75 // Note that this class runs on both the origin thread and a worker |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 ProxyResolverV8* v8_resolver(); | 130 ProxyResolverV8* v8_resolver(); |
| 137 base::MessageLoop* worker_loop(); | 131 base::MessageLoop* worker_loop(); |
| 138 HostResolver* host_resolver(); | 132 HostResolver* host_resolver(); |
| 139 ProxyResolverErrorObserver* error_observer(); | 133 ProxyResolverErrorObserver* error_observer(); |
| 140 NetLog* net_log(); | 134 NetLog* net_log(); |
| 141 | 135 |
| 142 // Invokes the user's callback. | 136 // Invokes the user's callback. |
| 143 void NotifyCaller(int result); | 137 void NotifyCaller(int result); |
| 144 void NotifyCallerOnOriginLoop(int result); | 138 void NotifyCallerOnOriginLoop(int result); |
| 145 | 139 |
| 146 void RecordMetrics() const; | |
| 147 | |
| 148 void Start(Operation op, bool blocking_dns, | 140 void Start(Operation op, bool blocking_dns, |
| 149 const CompletionCallback& callback); | 141 const CompletionCallback& callback); |
| 150 | 142 |
| 151 void ExecuteBlocking(); | 143 void ExecuteBlocking(); |
| 152 void ExecuteNonBlocking(); | 144 void ExecuteNonBlocking(); |
| 153 int ExecuteProxyResolver(); | 145 int ExecuteProxyResolver(); |
| 154 | 146 |
| 155 // Implementation of ProxyResolverv8::JSBindings | 147 // Implementation of ProxyResolverv8::JSBindings |
| 156 virtual bool ResolveDns(const std::string& host, | 148 virtual bool ResolveDns(const std::string& host, |
| 157 ResolveDnsOperation op, | 149 ResolveDnsOperation op, |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 bool pending_dns_completed_synchronously_; | 283 bool pending_dns_completed_synchronously_; |
| 292 | 284 |
| 293 // These are the inputs to DoDnsOperation(). Written on the worker thread, | 285 // These are the inputs to DoDnsOperation(). Written on the worker thread, |
| 294 // read by the origin thread. | 286 // read by the origin thread. |
| 295 std::string pending_dns_host_; | 287 std::string pending_dns_host_; |
| 296 ResolveDnsOperation pending_dns_op_; | 288 ResolveDnsOperation pending_dns_op_; |
| 297 | 289 |
| 298 // This contains the resolved address list that DoDnsOperation() fills in. | 290 // This contains the resolved address list that DoDnsOperation() fills in. |
| 299 // Used exclusively on the origin thread. | 291 // Used exclusively on the origin thread. |
| 300 AddressList pending_dns_addresses_; | 292 AddressList pending_dns_addresses_; |
| 301 | |
| 302 // --------------------------------------------------------------------------- | |
| 303 // Metrics for histograms | |
| 304 // --------------------------------------------------------------------------- | |
| 305 // These values are used solely for logging histograms. They do not affect | |
| 306 // the execution flow of requests. | |
| 307 | |
| 308 // The time when the proxy resolve request started. Used exclusively on the | |
| 309 // origin thread. | |
| 310 base::TimeTicks metrics_start_time_; | |
| 311 | |
| 312 // The time when the proxy resolve request completes on the worker thread. | |
| 313 // Written on the worker thread, read on the origin thread. | |
| 314 base::TimeTicks metrics_end_time_; | |
| 315 | |
| 316 // The time when PostDnsOperationAndWait() was called. Written on the worker | |
| 317 // thread, read by the origin thread. | |
| 318 base::TimeTicks metrics_pending_dns_start_; | |
| 319 | |
| 320 // The total amount of time that has been spent by the script waiting for | |
| 321 // DNS dependencies. This includes the time spent posting the task to | |
| 322 // the origin thread, up until the DNS result is found on the origin | |
| 323 // thread. It does not include any time spent waiting in the message loop | |
| 324 // for the worker thread, nor any time restarting or executing the | |
| 325 // script. Used exclusively on the origin thread. | |
| 326 base::TimeDelta metrics_dns_total_time_; | |
| 327 | |
| 328 // The following variables are initialized on the origin thread, | |
| 329 // incremented on the worker thread, and then read upon completion on the | |
| 330 // origin thread. The values are not expected to exceed the range of a uint8. | |
| 331 // If they do, then they will be clamped to 0xFF. | |
| 332 uint8 metrics_num_executions_; | |
| 333 uint8 metrics_num_unique_dns_; | |
| 334 uint8 metrics_num_alerts_; | |
| 335 uint8 metrics_num_errors_; | |
| 336 | |
| 337 // The time that the latest execution took (time spent inside of | |
| 338 // ExecuteProxyResolver(), which includes time spent in bindings too). | |
| 339 // Written on the worker thread, read on the origin thread. | |
| 340 base::TimeDelta metrics_execution_time_; | |
| 341 | |
| 342 // The cumulative time spent in ExecuteProxyResolver() that was ultimately | |
| 343 // discarded work. | |
| 344 // Written on the worker thread, read on the origin thread. | |
| 345 base::TimeDelta metrics_abandoned_execution_total_time_; | |
| 346 | |
| 347 // The duration that the worker thread was blocked waiting on DNS results from | |
| 348 // the origin thread, when operating in nonblocking mode. | |
| 349 // Written on the worker thread, read on the origin thread. | |
| 350 base::TimeDelta metrics_nonblocking_dns_wait_total_time_; | |
| 351 }; | 293 }; |
| 352 | 294 |
| 353 ProxyResolverV8Tracing::Job::Job(ProxyResolverV8Tracing* parent) | 295 ProxyResolverV8Tracing::Job::Job(ProxyResolverV8Tracing* parent) |
| 354 : origin_loop_(base::MessageLoopProxy::current()), | 296 : origin_loop_(base::MessageLoopProxy::current()), |
| 355 parent_(parent), | 297 parent_(parent), |
| 356 event_(true, false), | 298 event_(true, false), |
| 357 last_num_dns_(0), | 299 last_num_dns_(0), |
| 358 pending_dns_(NULL), | 300 pending_dns_(NULL) { |
| 359 metrics_num_executions_(0), | |
| 360 metrics_num_unique_dns_(0), | |
| 361 metrics_num_alerts_(0), | |
| 362 metrics_num_errors_(0) { | |
| 363 CheckIsOnOriginThread(); | 301 CheckIsOnOriginThread(); |
| 364 } | 302 } |
| 365 | 303 |
| 366 void ProxyResolverV8Tracing::Job::StartSetPacScript( | 304 void ProxyResolverV8Tracing::Job::StartSetPacScript( |
| 367 const scoped_refptr<ProxyResolverScriptData>& script_data, | 305 const scoped_refptr<ProxyResolverScriptData>& script_data, |
| 368 const CompletionCallback& callback) { | 306 const CompletionCallback& callback) { |
| 369 CheckIsOnOriginThread(); | 307 CheckIsOnOriginThread(); |
| 370 | 308 |
| 371 script_data_ = script_data; | 309 script_data_ = script_data; |
| 372 | 310 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 return parent_->error_observer_.get(); | 421 return parent_->error_observer_.get(); |
| 484 } | 422 } |
| 485 | 423 |
| 486 NetLog* ProxyResolverV8Tracing::Job::net_log() { | 424 NetLog* ProxyResolverV8Tracing::Job::net_log() { |
| 487 return parent_->net_log_; | 425 return parent_->net_log_; |
| 488 } | 426 } |
| 489 | 427 |
| 490 void ProxyResolverV8Tracing::Job::NotifyCaller(int result) { | 428 void ProxyResolverV8Tracing::Job::NotifyCaller(int result) { |
| 491 CheckIsOnWorkerThread(); | 429 CheckIsOnWorkerThread(); |
| 492 | 430 |
| 493 metrics_end_time_ = base::TimeTicks::Now(); | |
| 494 | |
| 495 origin_loop_->PostTask( | 431 origin_loop_->PostTask( |
| 496 FROM_HERE, | 432 FROM_HERE, |
| 497 base::Bind(&Job::NotifyCallerOnOriginLoop, this, result)); | 433 base::Bind(&Job::NotifyCallerOnOriginLoop, this, result)); |
| 498 } | 434 } |
| 499 | 435 |
| 500 void ProxyResolverV8Tracing::Job::NotifyCallerOnOriginLoop(int result) { | 436 void ProxyResolverV8Tracing::Job::NotifyCallerOnOriginLoop(int result) { |
| 501 CheckIsOnOriginThread(); | 437 CheckIsOnOriginThread(); |
| 502 | 438 |
| 503 if (cancelled_.IsSet()) | 439 if (cancelled_.IsSet()) |
| 504 return; | 440 return; |
| 505 | 441 |
| 506 DCHECK(!callback_.is_null()); | 442 DCHECK(!callback_.is_null()); |
| 507 DCHECK(!pending_dns_); | 443 DCHECK(!pending_dns_); |
| 508 | 444 |
| 509 if (operation_ == GET_PROXY_FOR_URL) { | 445 if (operation_ == GET_PROXY_FOR_URL) { |
| 510 RecordMetrics(); | |
| 511 *user_results_ = results_; | 446 *user_results_ = results_; |
| 512 } | 447 } |
| 513 | 448 |
| 514 // There is only ever 1 outstanding SET_PAC_SCRIPT job. It needs to be | 449 // There is only ever 1 outstanding SET_PAC_SCRIPT job. It needs to be |
| 515 // tracked to support cancellation. | 450 // tracked to support cancellation. |
| 516 if (operation_ == SET_PAC_SCRIPT) { | 451 if (operation_ == SET_PAC_SCRIPT) { |
| 517 DCHECK_EQ(parent_->set_pac_script_job_.get(), this); | 452 DCHECK_EQ(parent_->set_pac_script_job_.get(), this); |
| 518 parent_->set_pac_script_job_ = NULL; | 453 parent_->set_pac_script_job_ = NULL; |
| 519 } | 454 } |
| 520 | 455 |
| 521 CompletionCallback callback = callback_; | 456 CompletionCallback callback = callback_; |
| 522 ReleaseCallback(); | 457 ReleaseCallback(); |
| 523 callback.Run(result); | 458 callback.Run(result); |
| 524 | 459 |
| 525 owned_self_reference_ = NULL; | 460 owned_self_reference_ = NULL; |
| 526 } | 461 } |
| 527 | 462 |
| 528 void ProxyResolverV8Tracing::Job::RecordMetrics() const { | |
| 529 CheckIsOnOriginThread(); | |
| 530 DCHECK_EQ(GET_PROXY_FOR_URL, operation_); | |
| 531 | |
| 532 base::TimeTicks now = base::TimeTicks::Now(); | |
| 533 | |
| 534 // Metrics are output for each completed request to GetProxyForURL()). | |
| 535 // | |
| 536 // Note that a different set of histograms is used to record the metrics for | |
| 537 // requests that completed in non-blocking mode versus blocking mode. The | |
| 538 // expectation is for requests to complete in non-blocking mode each time. | |
| 539 // If they don't then something strange is happening, and the purpose of the | |
| 540 // seprate statistics is to better understand that trend. | |
| 541 #define UPDATE_HISTOGRAMS(base_name) \ | |
| 542 do {\ | |
| 543 UMA_HISTOGRAM_MEDIUM_TIMES(base_name "TotalTime", now - metrics_start_time_);\ | |
| 544 UMA_HISTOGRAM_MEDIUM_TIMES(base_name "TotalTimeWorkerThread",\ | |
| 545 metrics_end_time_ - metrics_start_time_);\ | |
| 546 UMA_HISTOGRAM_TIMES(base_name "OriginThreadLatency",\ | |
| 547 now - metrics_end_time_);\ | |
| 548 UMA_HISTOGRAM_MEDIUM_TIMES(base_name "TotalTimeDNS",\ | |
| 549 metrics_dns_total_time_);\ | |
| 550 UMA_HISTOGRAM_MEDIUM_TIMES(base_name "ExecutionTime",\ | |
| 551 metrics_execution_time_);\ | |
| 552 UMA_HISTOGRAM_MEDIUM_TIMES(base_name "AbandonedExecutionTotalTime",\ | |
| 553 metrics_abandoned_execution_total_time_);\ | |
| 554 UMA_HISTOGRAM_MEDIUM_TIMES(base_name "DnsWaitTotalTime",\ | |
| 555 metrics_nonblocking_dns_wait_total_time_);\ | |
| 556 UMA_HISTOGRAM_CUSTOM_COUNTS(\ | |
| 557 base_name "NumRestarts", metrics_num_executions_ - 1,\ | |
| 558 1, kMaxUniqueResolveDnsPerExec, kMaxUniqueResolveDnsPerExec);\ | |
| 559 UMA_HISTOGRAM_CUSTOM_COUNTS(\ | |
| 560 base_name "UniqueDNS", metrics_num_unique_dns_,\ | |
| 561 1, kMaxUniqueResolveDnsPerExec, kMaxUniqueResolveDnsPerExec);\ | |
| 562 UMA_HISTOGRAM_COUNTS_100(base_name "NumAlerts", metrics_num_alerts_);\ | |
| 563 UMA_HISTOGRAM_CUSTOM_COUNTS(\ | |
| 564 base_name "NumErrors", metrics_num_errors_, 1, 10, 10);\ | |
| 565 } while (false) | |
| 566 | |
| 567 if (!blocking_dns_) | |
| 568 UPDATE_HISTOGRAMS("Net.ProxyResolver."); | |
| 569 else | |
| 570 UPDATE_HISTOGRAMS("Net.ProxyResolver.BlockingDNSMode."); | |
| 571 | |
| 572 #undef UPDATE_HISTOGRAMS | |
| 573 | |
| 574 // Histograms to better understand http://crbug.com/240536 -- long | |
| 575 // URLs can cause a significant slowdown in PAC execution. Figure out how | |
| 576 // severe this is in the wild. | |
| 577 if (!blocking_dns_) { | |
| 578 size_t url_size = url_.spec().size(); | |
| 579 | |
| 580 UMA_HISTOGRAM_CUSTOM_COUNTS( | |
| 581 "Net.ProxyResolver.URLSize", url_size, 1, 200000, 50); | |
| 582 | |
| 583 if (url_size > 2048) { | |
| 584 UMA_HISTOGRAM_MEDIUM_TIMES("Net.ProxyResolver.ExecutionTime_UrlOver2K", | |
| 585 metrics_execution_time_); | |
| 586 } | |
| 587 | |
| 588 if (url_size > 4096) { | |
| 589 UMA_HISTOGRAM_MEDIUM_TIMES("Net.ProxyResolver.ExecutionTime_UrlOver4K", | |
| 590 metrics_execution_time_); | |
| 591 } | |
| 592 | |
| 593 if (url_size > 8192) { | |
| 594 UMA_HISTOGRAM_MEDIUM_TIMES("Net.ProxyResolver.ExecutionTime_UrlOver8K", | |
| 595 metrics_execution_time_); | |
| 596 } | |
| 597 | |
| 598 if (url_size > 131072) { | |
| 599 UMA_HISTOGRAM_MEDIUM_TIMES("Net.ProxyResolver.ExecutionTime_UrlOver128K", | |
| 600 metrics_execution_time_); | |
| 601 } | |
| 602 } | |
| 603 } | |
| 604 | |
| 605 | |
| 606 void ProxyResolverV8Tracing::Job::Start(Operation op, bool blocking_dns, | 463 void ProxyResolverV8Tracing::Job::Start(Operation op, bool blocking_dns, |
| 607 const CompletionCallback& callback) { | 464 const CompletionCallback& callback) { |
| 608 CheckIsOnOriginThread(); | 465 CheckIsOnOriginThread(); |
| 609 | 466 |
| 610 metrics_start_time_ = base::TimeTicks::Now(); | |
| 611 operation_ = op; | 467 operation_ = op; |
| 612 blocking_dns_ = blocking_dns; | 468 blocking_dns_ = blocking_dns; |
| 613 SetCallback(callback); | 469 SetCallback(callback); |
| 614 | 470 |
| 615 owned_self_reference_ = this; | 471 owned_self_reference_ = this; |
| 616 | 472 |
| 617 worker_loop()->PostTask(FROM_HERE, | 473 worker_loop()->PostTask(FROM_HERE, |
| 618 blocking_dns_ ? base::Bind(&Job::ExecuteBlocking, this) : | 474 blocking_dns_ ? base::Bind(&Job::ExecuteBlocking, this) : |
| 619 base::Bind(&Job::ExecuteNonBlocking, this)); | 475 base::Bind(&Job::ExecuteNonBlocking, this)); |
| 620 } | 476 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 638 | 494 |
| 639 // Reset state for the current execution. | 495 // Reset state for the current execution. |
| 640 abandoned_ = false; | 496 abandoned_ = false; |
| 641 num_dns_ = 0; | 497 num_dns_ = 0; |
| 642 alerts_and_errors_.clear(); | 498 alerts_and_errors_.clear(); |
| 643 alerts_and_errors_byte_cost_ = 0; | 499 alerts_and_errors_byte_cost_ = 0; |
| 644 should_restart_with_blocking_dns_ = false; | 500 should_restart_with_blocking_dns_ = false; |
| 645 | 501 |
| 646 int result = ExecuteProxyResolver(); | 502 int result = ExecuteProxyResolver(); |
| 647 | 503 |
| 648 if (abandoned_) | |
| 649 metrics_abandoned_execution_total_time_ += metrics_execution_time_; | |
| 650 | |
| 651 if (should_restart_with_blocking_dns_) { | 504 if (should_restart_with_blocking_dns_) { |
| 652 DCHECK(!blocking_dns_); | 505 DCHECK(!blocking_dns_); |
| 653 DCHECK(abandoned_); | 506 DCHECK(abandoned_); |
| 654 blocking_dns_ = true; | 507 blocking_dns_ = true; |
| 655 ExecuteBlocking(); | 508 ExecuteBlocking(); |
| 656 return; | 509 return; |
| 657 } | 510 } |
| 658 | 511 |
| 659 if (abandoned_) | 512 if (abandoned_) |
| 660 return; | 513 return; |
| 661 | 514 |
| 662 DispatchBufferedAlertsAndErrors(); | 515 DispatchBufferedAlertsAndErrors(); |
| 663 NotifyCaller(result); | 516 NotifyCaller(result); |
| 664 } | 517 } |
| 665 | 518 |
| 666 int ProxyResolverV8Tracing::Job::ExecuteProxyResolver() { | 519 int ProxyResolverV8Tracing::Job::ExecuteProxyResolver() { |
| 667 IncrementWithoutOverflow(&metrics_num_executions_); | |
| 668 | |
| 669 base::TimeTicks start = base::TimeTicks::Now(); | |
| 670 | |
| 671 JSBindings* prev_bindings = v8_resolver()->js_bindings(); | 520 JSBindings* prev_bindings = v8_resolver()->js_bindings(); |
| 672 v8_resolver()->set_js_bindings(this); | 521 v8_resolver()->set_js_bindings(this); |
| 673 | 522 |
| 674 int result = ERR_UNEXPECTED; // Initialized to silence warnings. | 523 int result = ERR_UNEXPECTED; // Initialized to silence warnings. |
| 675 | 524 |
| 676 switch (operation_) { | 525 switch (operation_) { |
| 677 case SET_PAC_SCRIPT: | 526 case SET_PAC_SCRIPT: |
| 678 result = v8_resolver()->SetPacScript( | 527 result = v8_resolver()->SetPacScript( |
| 679 script_data_, CompletionCallback()); | 528 script_data_, CompletionCallback()); |
| 680 break; | 529 break; |
| 681 case GET_PROXY_FOR_URL: | 530 case GET_PROXY_FOR_URL: |
| 682 result = v8_resolver()->GetProxyForURL( | 531 result = v8_resolver()->GetProxyForURL( |
| 683 url_, | 532 url_, |
| 684 // Important: Do not write directly into |user_results_|, since if the | 533 // Important: Do not write directly into |user_results_|, since if the |
| 685 // request were to be cancelled from the origin thread, must guarantee | 534 // request were to be cancelled from the origin thread, must guarantee |
| 686 // that |user_results_| is not accessed anymore. | 535 // that |user_results_| is not accessed anymore. |
| 687 &results_, | 536 &results_, |
| 688 CompletionCallback(), | 537 CompletionCallback(), |
| 689 NULL, | 538 NULL, |
| 690 bound_net_log_); | 539 bound_net_log_); |
| 691 break; | 540 break; |
| 692 } | 541 } |
| 693 | 542 |
| 694 v8_resolver()->set_js_bindings(prev_bindings); | 543 v8_resolver()->set_js_bindings(prev_bindings); |
| 695 | 544 |
| 696 metrics_execution_time_ = base::TimeTicks::Now() - start; | |
| 697 | |
| 698 return result; | 545 return result; |
| 699 } | 546 } |
| 700 | 547 |
| 701 bool ProxyResolverV8Tracing::Job::ResolveDns(const std::string& host, | 548 bool ProxyResolverV8Tracing::Job::ResolveDns(const std::string& host, |
| 702 ResolveDnsOperation op, | 549 ResolveDnsOperation op, |
| 703 std::string* output, | 550 std::string* output, |
| 704 bool* terminate) { | 551 bool* terminate) { |
| 705 if (cancelled_.IsSet()) { | 552 if (cancelled_.IsSet()) { |
| 706 *terminate = true; | 553 *terminate = true; |
| 707 return false; | 554 return false; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 731 std::string* output) { | 578 std::string* output) { |
| 732 CheckIsOnWorkerThread(); | 579 CheckIsOnWorkerThread(); |
| 733 | 580 |
| 734 // Check if the DNS result for this host has already been cached. | 581 // Check if the DNS result for this host has already been cached. |
| 735 bool rv; | 582 bool rv; |
| 736 if (GetDnsFromLocalCache(host, op, output, &rv)) { | 583 if (GetDnsFromLocalCache(host, op, output, &rv)) { |
| 737 // Yay, cache hit! | 584 // Yay, cache hit! |
| 738 return rv; | 585 return rv; |
| 739 } | 586 } |
| 740 | 587 |
| 741 // If the host was not in the local cache, this is a new hostname. | |
| 742 IncrementWithoutOverflow(&metrics_num_unique_dns_); | |
| 743 | |
| 744 if (dns_cache_.size() >= kMaxUniqueResolveDnsPerExec) { | 588 if (dns_cache_.size() >= kMaxUniqueResolveDnsPerExec) { |
| 745 // Safety net for scripts with unexpectedly many DNS calls. | 589 // Safety net for scripts with unexpectedly many DNS calls. |
| 746 // We will continue running to completion, but will fail every | 590 // We will continue running to completion, but will fail every |
| 747 // subsequent DNS request. | 591 // subsequent DNS request. |
| 748 return false; | 592 return false; |
| 749 } | 593 } |
| 750 | 594 |
| 751 if (!PostDnsOperationAndWait(host, op, NULL)) | 595 if (!PostDnsOperationAndWait(host, op, NULL)) |
| 752 return false; // Was cancelled. | 596 return false; // Was cancelled. |
| 753 | 597 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 769 | 613 |
| 770 num_dns_ += 1; | 614 num_dns_ += 1; |
| 771 | 615 |
| 772 // Check if the DNS result for this host has already been cached. | 616 // Check if the DNS result for this host has already been cached. |
| 773 bool rv; | 617 bool rv; |
| 774 if (GetDnsFromLocalCache(host, op, output, &rv)) { | 618 if (GetDnsFromLocalCache(host, op, output, &rv)) { |
| 775 // Yay, cache hit! | 619 // Yay, cache hit! |
| 776 return rv; | 620 return rv; |
| 777 } | 621 } |
| 778 | 622 |
| 779 // If the host was not in the local cache, then this is a new hostname. | |
| 780 IncrementWithoutOverflow(&metrics_num_unique_dns_); | |
| 781 | |
| 782 if (num_dns_ <= last_num_dns_) { | 623 if (num_dns_ <= last_num_dns_) { |
| 783 // The sequence of DNS operations is different from last time! | 624 // The sequence of DNS operations is different from last time! |
| 784 ScheduleRestartWithBlockingDns(); | 625 ScheduleRestartWithBlockingDns(); |
| 785 *terminate = true; | 626 *terminate = true; |
| 786 return false; | 627 return false; |
| 787 } | 628 } |
| 788 | 629 |
| 789 if (dns_cache_.size() >= kMaxUniqueResolveDnsPerExec) { | 630 if (dns_cache_.size() >= kMaxUniqueResolveDnsPerExec) { |
| 790 // Safety net for scripts with unexpectedly many DNS calls. | 631 // Safety net for scripts with unexpectedly many DNS calls. |
| 791 return false; | 632 return false; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 808 abandoned_ = true; | 649 abandoned_ = true; |
| 809 *terminate = true; | 650 *terminate = true; |
| 810 last_num_dns_ = num_dns_; | 651 last_num_dns_ = num_dns_; |
| 811 return false; | 652 return false; |
| 812 } | 653 } |
| 813 | 654 |
| 814 bool ProxyResolverV8Tracing::Job::PostDnsOperationAndWait( | 655 bool ProxyResolverV8Tracing::Job::PostDnsOperationAndWait( |
| 815 const std::string& host, ResolveDnsOperation op, | 656 const std::string& host, ResolveDnsOperation op, |
| 816 bool* completed_synchronously) { | 657 bool* completed_synchronously) { |
| 817 | 658 |
| 818 base::TimeTicks start = base::TimeTicks::Now(); | |
| 819 | |
| 820 // Post the DNS request to the origin thread. | 659 // Post the DNS request to the origin thread. |
| 821 DCHECK(!pending_dns_); | 660 DCHECK(!pending_dns_); |
| 822 metrics_pending_dns_start_ = base::TimeTicks::Now(); | |
| 823 pending_dns_host_ = host; | 661 pending_dns_host_ = host; |
| 824 pending_dns_op_ = op; | 662 pending_dns_op_ = op; |
| 825 origin_loop_->PostTask(FROM_HERE, base::Bind(&Job::DoDnsOperation, this)); | 663 origin_loop_->PostTask(FROM_HERE, base::Bind(&Job::DoDnsOperation, this)); |
| 826 | 664 |
| 827 event_.Wait(); | 665 event_.Wait(); |
| 828 event_.Reset(); | 666 event_.Reset(); |
| 829 | 667 |
| 830 if (cancelled_.IsSet()) | 668 if (cancelled_.IsSet()) |
| 831 return false; | 669 return false; |
| 832 | 670 |
| 833 if (completed_synchronously) | 671 if (completed_synchronously) |
| 834 *completed_synchronously = pending_dns_completed_synchronously_; | 672 *completed_synchronously = pending_dns_completed_synchronously_; |
| 835 | 673 |
| 836 if (!blocking_dns_) | |
| 837 metrics_nonblocking_dns_wait_total_time_ += base::TimeTicks::Now() - start; | |
| 838 | |
| 839 return true; | 674 return true; |
| 840 } | 675 } |
| 841 | 676 |
| 842 void ProxyResolverV8Tracing::Job::DoDnsOperation() { | 677 void ProxyResolverV8Tracing::Job::DoDnsOperation() { |
| 843 CheckIsOnOriginThread(); | 678 CheckIsOnOriginThread(); |
| 844 DCHECK(!pending_dns_); | 679 DCHECK(!pending_dns_); |
| 845 | 680 |
| 846 if (cancelled_.IsSet()) | 681 if (cancelled_.IsSet()) |
| 847 return; | 682 return; |
| 848 | 683 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 884 void ProxyResolverV8Tracing::Job::OnDnsOperationComplete(int result) { | 719 void ProxyResolverV8Tracing::Job::OnDnsOperationComplete(int result) { |
| 885 CheckIsOnOriginThread(); | 720 CheckIsOnOriginThread(); |
| 886 | 721 |
| 887 DCHECK(!cancelled_.IsSet()); | 722 DCHECK(!cancelled_.IsSet()); |
| 888 DCHECK(pending_dns_completed_synchronously_ == (pending_dns_ == NULL)); | 723 DCHECK(pending_dns_completed_synchronously_ == (pending_dns_ == NULL)); |
| 889 | 724 |
| 890 SaveDnsToLocalCache(pending_dns_host_, pending_dns_op_, result, | 725 SaveDnsToLocalCache(pending_dns_host_, pending_dns_op_, result, |
| 891 pending_dns_addresses_); | 726 pending_dns_addresses_); |
| 892 pending_dns_ = NULL; | 727 pending_dns_ = NULL; |
| 893 | 728 |
| 894 metrics_dns_total_time_ += | |
| 895 base::TimeTicks::Now() - metrics_pending_dns_start_; | |
| 896 | |
| 897 if (blocking_dns_) { | 729 if (blocking_dns_) { |
| 898 event_.Signal(); | 730 event_.Signal(); |
| 899 return; | 731 return; |
| 900 } | 732 } |
| 901 | 733 |
| 902 if (!blocking_dns_ && !pending_dns_completed_synchronously_) { | 734 if (!blocking_dns_ && !pending_dns_completed_synchronously_) { |
| 903 // Restart. This time it should make more progress due to having | 735 // Restart. This time it should make more progress due to having |
| 904 // cached items. | 736 // cached items. |
| 905 worker_loop()->PostTask(FROM_HERE, | 737 worker_loop()->PostTask(FROM_HERE, |
| 906 base::Bind(&Job::ExecuteNonBlocking, this)); | 738 base::Bind(&Job::ExecuteNonBlocking, this)); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1049 // If this happens, then some information will get written to the NetLog | 881 // If this happens, then some information will get written to the NetLog |
| 1050 // needlessly, however the NetLog will still be alive so it shouldn't cause | 882 // needlessly, however the NetLog will still be alive so it shouldn't cause |
| 1051 // problems. | 883 // problems. |
| 1052 if (cancelled_.IsSet()) | 884 if (cancelled_.IsSet()) |
| 1053 return; | 885 return; |
| 1054 | 886 |
| 1055 if (is_alert) { | 887 if (is_alert) { |
| 1056 // ------------------- | 888 // ------------------- |
| 1057 // alert | 889 // alert |
| 1058 // ------------------- | 890 // ------------------- |
| 1059 IncrementWithoutOverflow(&metrics_num_alerts_); | |
| 1060 VLOG(1) << "PAC-alert: " << message; | 891 VLOG(1) << "PAC-alert: " << message; |
| 1061 | 892 |
| 1062 // Send to the NetLog. | 893 // Send to the NetLog. |
| 1063 LogEventToCurrentRequestAndGlobally( | 894 LogEventToCurrentRequestAndGlobally( |
| 1064 NetLog::TYPE_PAC_JAVASCRIPT_ALERT, | 895 NetLog::TYPE_PAC_JAVASCRIPT_ALERT, |
| 1065 NetLog::StringCallback("message", &message)); | 896 NetLog::StringCallback("message", &message)); |
| 1066 } else { | 897 } else { |
| 1067 // ------------------- | 898 // ------------------- |
| 1068 // error | 899 // error |
| 1069 // ------------------- | 900 // ------------------- |
| 1070 IncrementWithoutOverflow(&metrics_num_errors_); | |
| 1071 if (line_number == -1) | 901 if (line_number == -1) |
| 1072 VLOG(1) << "PAC-error: " << message; | 902 VLOG(1) << "PAC-error: " << message; |
| 1073 else | 903 else |
| 1074 VLOG(1) << "PAC-error: " << "line: " << line_number << ": " << message; | 904 VLOG(1) << "PAC-error: " << "line: " << line_number << ": " << message; |
| 1075 | 905 |
| 1076 // Send the error to the NetLog. | 906 // Send the error to the NetLog. |
| 1077 LogEventToCurrentRequestAndGlobally( | 907 LogEventToCurrentRequestAndGlobally( |
| 1078 NetLog::TYPE_PAC_JAVASCRIPT_ERROR, | 908 NetLog::TYPE_PAC_JAVASCRIPT_ERROR, |
| 1079 base::Bind(&NetLogErrorCallback, line_number, &message)); | 909 base::Bind(&NetLogErrorCallback, line_number, &message)); |
| 1080 | 910 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1171 DCHECK(!set_pac_script_job_.get()); | 1001 DCHECK(!set_pac_script_job_.get()); |
| 1172 CHECK_EQ(0, num_outstanding_callbacks_); | 1002 CHECK_EQ(0, num_outstanding_callbacks_); |
| 1173 | 1003 |
| 1174 set_pac_script_job_ = new Job(this); | 1004 set_pac_script_job_ = new Job(this); |
| 1175 set_pac_script_job_->StartSetPacScript(script_data, callback); | 1005 set_pac_script_job_->StartSetPacScript(script_data, callback); |
| 1176 | 1006 |
| 1177 return ERR_IO_PENDING; | 1007 return ERR_IO_PENDING; |
| 1178 } | 1008 } |
| 1179 | 1009 |
| 1180 } // namespace net | 1010 } // namespace net |
| OLD | NEW |