| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/multi_threaded_proxy_resolver.h" | 5 #include "net/proxy/multi_threaded_proxy_resolver.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/message_loop/message_loop_proxy.h" | 9 #include "base/message_loop/message_loop_proxy.h" |
| 10 #include "base/metrics/histogram.h" | |
| 11 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 12 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.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 "net/base/net_errors.h" | 14 #include "net/base/net_errors.h" |
| 16 #include "net/base/net_log.h" | 15 #include "net/base/net_log.h" |
| 17 #include "net/proxy/proxy_info.h" | 16 #include "net/proxy/proxy_info.h" |
| 18 | 17 |
| 19 // TODO(eroman): Have the MultiThreadedProxyResolver clear its PAC script | 18 // TODO(eroman): Have the MultiThreadedProxyResolver clear its PAC script |
| 20 // data when SetPacScript fails. That will reclaim memory when | 19 // data when SetPacScript fails. That will reclaim memory when |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 GetProxyForURLJob(const GURL& url, | 211 GetProxyForURLJob(const GURL& url, |
| 213 ProxyInfo* results, | 212 ProxyInfo* results, |
| 214 const CompletionCallback& callback, | 213 const CompletionCallback& callback, |
| 215 const BoundNetLog& net_log) | 214 const BoundNetLog& net_log) |
| 216 : Job(TYPE_GET_PROXY_FOR_URL, callback), | 215 : Job(TYPE_GET_PROXY_FOR_URL, callback), |
| 217 results_(results), | 216 results_(results), |
| 218 net_log_(net_log), | 217 net_log_(net_log), |
| 219 url_(url), | 218 url_(url), |
| 220 was_waiting_for_thread_(false) { | 219 was_waiting_for_thread_(false) { |
| 221 DCHECK(!callback.is_null()); | 220 DCHECK(!callback.is_null()); |
| 222 start_time_ = base::TimeTicks::Now(); | |
| 223 } | 221 } |
| 224 | 222 |
| 225 BoundNetLog* net_log() { return &net_log_; } | 223 BoundNetLog* net_log() { return &net_log_; } |
| 226 | 224 |
| 227 virtual void WaitingForThread() OVERRIDE { | 225 virtual void WaitingForThread() OVERRIDE { |
| 228 was_waiting_for_thread_ = true; | 226 was_waiting_for_thread_ = true; |
| 229 net_log_.BeginEvent(NetLog::TYPE_WAITING_FOR_PROXY_RESOLVER_THREAD); | 227 net_log_.BeginEvent(NetLog::TYPE_WAITING_FOR_PROXY_RESOLVER_THREAD); |
| 230 } | 228 } |
| 231 | 229 |
| 232 virtual void FinishedWaitingForThread() OVERRIDE { | 230 virtual void FinishedWaitingForThread() OVERRIDE { |
| 233 DCHECK(executor()); | 231 DCHECK(executor()); |
| 234 | 232 |
| 235 submitted_to_thread_time_ = base::TimeTicks::Now(); | |
| 236 | |
| 237 if (was_waiting_for_thread_) { | 233 if (was_waiting_for_thread_) { |
| 238 net_log_.EndEvent(NetLog::TYPE_WAITING_FOR_PROXY_RESOLVER_THREAD); | 234 net_log_.EndEvent(NetLog::TYPE_WAITING_FOR_PROXY_RESOLVER_THREAD); |
| 239 } | 235 } |
| 240 | 236 |
| 241 net_log_.AddEvent( | 237 net_log_.AddEvent( |
| 242 NetLog::TYPE_SUBMITTED_TO_RESOLVER_THREAD, | 238 NetLog::TYPE_SUBMITTED_TO_RESOLVER_THREAD, |
| 243 NetLog::IntegerCallback("thread_number", executor()->thread_number())); | 239 NetLog::IntegerCallback("thread_number", executor()->thread_number())); |
| 244 } | 240 } |
| 245 | 241 |
| 246 // Runs on the worker thread. | 242 // Runs on the worker thread. |
| 247 virtual void Run(scoped_refptr<base::MessageLoopProxy> origin_loop) OVERRIDE { | 243 virtual void Run(scoped_refptr<base::MessageLoopProxy> origin_loop) OVERRIDE { |
| 248 ProxyResolver* resolver = executor()->resolver(); | 244 ProxyResolver* resolver = executor()->resolver(); |
| 249 int rv = resolver->GetProxyForURL( | 245 int rv = resolver->GetProxyForURL( |
| 250 url_, &results_buf_, CompletionCallback(), NULL, net_log_); | 246 url_, &results_buf_, CompletionCallback(), NULL, net_log_); |
| 251 DCHECK_NE(rv, ERR_IO_PENDING); | 247 DCHECK_NE(rv, ERR_IO_PENDING); |
| 252 | 248 |
| 253 origin_loop->PostTask( | 249 origin_loop->PostTask( |
| 254 FROM_HERE, | 250 FROM_HERE, |
| 255 base::Bind(&GetProxyForURLJob::QueryComplete, this, rv)); | 251 base::Bind(&GetProxyForURLJob::QueryComplete, this, rv)); |
| 256 } | 252 } |
| 257 | 253 |
| 258 protected: | 254 protected: |
| 259 virtual ~GetProxyForURLJob() {} | 255 virtual ~GetProxyForURLJob() {} |
| 260 | 256 |
| 261 private: | 257 private: |
| 262 // Runs the completion callback on the origin thread. | 258 // Runs the completion callback on the origin thread. |
| 263 void QueryComplete(int result_code) { | 259 void QueryComplete(int result_code) { |
| 264 // The Job may have been cancelled after it was started. | 260 // The Job may have been cancelled after it was started. |
| 265 if (!was_cancelled()) { | 261 if (!was_cancelled()) { |
| 266 RecordPerformanceMetrics(); | |
| 267 if (result_code >= OK) { // Note: unit-tests use values > 0. | 262 if (result_code >= OK) { // Note: unit-tests use values > 0. |
| 268 results_->Use(results_buf_); | 263 results_->Use(results_buf_); |
| 269 } | 264 } |
| 270 RunUserCallback(result_code); | 265 RunUserCallback(result_code); |
| 271 } | 266 } |
| 272 OnJobCompleted(); | 267 OnJobCompleted(); |
| 273 } | 268 } |
| 274 | 269 |
| 275 void RecordPerformanceMetrics() { | |
| 276 DCHECK(!was_cancelled()); | |
| 277 | |
| 278 base::TimeTicks now = base::TimeTicks::Now(); | |
| 279 | |
| 280 // Log the total time the request took to complete. | |
| 281 UMA_HISTOGRAM_MEDIUM_TIMES("Net.MTPR_GetProxyForUrl_Time", | |
| 282 now - start_time_); | |
| 283 | |
| 284 // Log the time the request was stalled waiting for a thread to free up. | |
| 285 UMA_HISTOGRAM_MEDIUM_TIMES("Net.MTPR_GetProxyForUrl_Thread_Wait_Time", | |
| 286 submitted_to_thread_time_ - start_time_); | |
| 287 } | |
| 288 | |
| 289 // Must only be used on the "origin" thread. | 270 // Must only be used on the "origin" thread. |
| 290 ProxyInfo* results_; | 271 ProxyInfo* results_; |
| 291 | 272 |
| 292 // Can be used on either "origin" or worker thread. | 273 // Can be used on either "origin" or worker thread. |
| 293 BoundNetLog net_log_; | 274 BoundNetLog net_log_; |
| 294 const GURL url_; | 275 const GURL url_; |
| 295 | 276 |
| 296 // Usable from within DoQuery on the worker thread. | 277 // Usable from within DoQuery on the worker thread. |
| 297 ProxyInfo results_buf_; | 278 ProxyInfo results_buf_; |
| 298 | 279 |
| 299 base::TimeTicks start_time_; | |
| 300 base::TimeTicks submitted_to_thread_time_; | |
| 301 | |
| 302 bool was_waiting_for_thread_; | 280 bool was_waiting_for_thread_; |
| 303 }; | 281 }; |
| 304 | 282 |
| 305 // MultiThreadedProxyResolver::Executor ---------------------------------------- | 283 // MultiThreadedProxyResolver::Executor ---------------------------------------- |
| 306 | 284 |
| 307 MultiThreadedProxyResolver::Executor::Executor( | 285 MultiThreadedProxyResolver::Executor::Executor( |
| 308 MultiThreadedProxyResolver* coordinator, | 286 MultiThreadedProxyResolver* coordinator, |
| 309 ProxyResolver* resolver, | 287 ProxyResolver* resolver, |
| 310 int thread_number) | 288 int thread_number) |
| 311 : coordinator_(coordinator), | 289 : coordinator_(coordinator), |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 return; | 531 return; |
| 554 | 532 |
| 555 // Get the next job to process (FIFO). Transfer it from the pending queue | 533 // Get the next job to process (FIFO). Transfer it from the pending queue |
| 556 // to the executor. | 534 // to the executor. |
| 557 scoped_refptr<Job> job = pending_jobs_.front(); | 535 scoped_refptr<Job> job = pending_jobs_.front(); |
| 558 pending_jobs_.pop_front(); | 536 pending_jobs_.pop_front(); |
| 559 executor->StartJob(job.get()); | 537 executor->StartJob(job.get()); |
| 560 } | 538 } |
| 561 | 539 |
| 562 } // namespace net | 540 } // namespace net |
| OLD | NEW |