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

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

Issue 266243004: Clang format slam. Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 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 | Annotate | Revision Log
OLDNEW
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" 10 #include "base/metrics/histogram.h"
11 #include "base/strings/string_util.h" 11 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h" 12 #include "base/strings/stringprintf.h"
13 #include "base/threading/thread.h" 13 #include "base/threading/thread.h"
14 #include "base/threading/thread_restrictions.h" 14 #include "base/threading/thread_restrictions.h"
15 #include "net/base/net_errors.h" 15 #include "net/base/net_errors.h"
16 #include "net/base/net_log.h" 16 #include "net/base/net_log.h"
17 #include "net/proxy/proxy_info.h" 17 #include "net/proxy/proxy_info.h"
18 18
19 // TODO(eroman): Have the MultiThreadedProxyResolver clear its PAC script 19 // TODO(eroman): Have the MultiThreadedProxyResolver clear its PAC script
20 // data when SetPacScript fails. That will reclaim memory when 20 // data when SetPacScript fails. That will reclaim memory when
21 // testing bogus scripts. 21 // testing bogus scripts.
22 22
23 namespace net { 23 namespace net {
24 24
25 // An "executor" is a job-runner for PAC requests. It encapsulates a worker 25 // An "executor" is a job-runner for PAC requests. It encapsulates a worker
26 // thread and a synchronous ProxyResolver (which will be operated on said 26 // thread and a synchronous ProxyResolver (which will be operated on said
27 // thread.) 27 // thread.)
28 class MultiThreadedProxyResolver::Executor 28 class MultiThreadedProxyResolver::Executor
29 : public base::RefCountedThreadSafe<MultiThreadedProxyResolver::Executor > { 29 : public base::RefCountedThreadSafe<MultiThreadedProxyResolver::Executor> {
30 public: 30 public:
31 // |coordinator| must remain valid throughout our lifetime. It is used to 31 // |coordinator| must remain valid throughout our lifetime. It is used to
32 // signal when the executor is ready to receive work by calling 32 // signal when the executor is ready to receive work by calling
33 // |coordinator->OnExecutorReady()|. 33 // |coordinator->OnExecutorReady()|.
34 // The constructor takes ownership of |resolver|. 34 // The constructor takes ownership of |resolver|.
35 // |thread_number| is an identifier used when naming the worker thread. 35 // |thread_number| is an identifier used when naming the worker thread.
36 Executor(MultiThreadedProxyResolver* coordinator, 36 Executor(MultiThreadedProxyResolver* coordinator,
37 ProxyResolver* resolver, 37 ProxyResolver* resolver,
38 int thread_number); 38 int thread_number);
39 39
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 enum Type { 84 enum Type {
85 TYPE_GET_PROXY_FOR_URL, 85 TYPE_GET_PROXY_FOR_URL,
86 TYPE_SET_PAC_SCRIPT, 86 TYPE_SET_PAC_SCRIPT,
87 TYPE_SET_PAC_SCRIPT_INTERNAL, 87 TYPE_SET_PAC_SCRIPT_INTERNAL,
88 }; 88 };
89 89
90 Job(Type type, const CompletionCallback& callback) 90 Job(Type type, const CompletionCallback& callback)
91 : type_(type), 91 : type_(type),
92 callback_(callback), 92 callback_(callback),
93 executor_(NULL), 93 executor_(NULL),
94 was_cancelled_(false) { 94 was_cancelled_(false) {}
95 }
96 95
97 void set_executor(Executor* executor) { 96 void set_executor(Executor* executor) { executor_ = executor; }
98 executor_ = executor;
99 }
100 97
101 // The "executor" is the job runner that is scheduling this job. If 98 // The "executor" is the job runner that is scheduling this job. If
102 // this job has not been submitted to an executor yet, this will be 99 // this job has not been submitted to an executor yet, this will be
103 // NULL (and we know it hasn't started yet). 100 // NULL (and we know it hasn't started yet).
104 Executor* executor() { 101 Executor* executor() { return executor_; }
105 return executor_;
106 }
107 102
108 // Mark the job as having been cancelled. 103 // Mark the job as having been cancelled.
109 void Cancel() { 104 void Cancel() { was_cancelled_ = true; }
110 was_cancelled_ = true;
111 }
112 105
113 // Returns true if Cancel() has been called. 106 // Returns true if Cancel() has been called.
114 bool was_cancelled() const { return was_cancelled_; } 107 bool was_cancelled() const { return was_cancelled_; }
115 108
116 Type type() const { return type_; } 109 Type type() const { return type_; }
117 110
118 // Returns true if this job still has a user callback. Some jobs 111 // Returns true if this job still has a user callback. Some jobs
119 // do not have a user callback, because they were helper jobs 112 // do not have a user callback, because they were helper jobs
120 // scheduled internally (for example TYPE_SET_PAC_SCRIPT_INTERNAL). 113 // scheduled internally (for example TYPE_SET_PAC_SCRIPT_INTERNAL).
121 // 114 //
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 }; 155 };
163 156
164 // MultiThreadedProxyResolver::SetPacScriptJob --------------------------------- 157 // MultiThreadedProxyResolver::SetPacScriptJob ---------------------------------
165 158
166 // Runs on the worker thread to call ProxyResolver::SetPacScript. 159 // Runs on the worker thread to call ProxyResolver::SetPacScript.
167 class MultiThreadedProxyResolver::SetPacScriptJob 160 class MultiThreadedProxyResolver::SetPacScriptJob
168 : public MultiThreadedProxyResolver::Job { 161 : public MultiThreadedProxyResolver::Job {
169 public: 162 public:
170 SetPacScriptJob(const scoped_refptr<ProxyResolverScriptData>& script_data, 163 SetPacScriptJob(const scoped_refptr<ProxyResolverScriptData>& script_data,
171 const CompletionCallback& callback) 164 const CompletionCallback& callback)
172 : Job(!callback.is_null() ? TYPE_SET_PAC_SCRIPT : 165 : Job(!callback.is_null() ? TYPE_SET_PAC_SCRIPT
173 TYPE_SET_PAC_SCRIPT_INTERNAL, 166 : TYPE_SET_PAC_SCRIPT_INTERNAL,
174 callback), 167 callback),
175 script_data_(script_data) { 168 script_data_(script_data) {}
176 }
177 169
178 // Runs on the worker thread. 170 // Runs on the worker thread.
179 virtual void Run(scoped_refptr<base::MessageLoopProxy> origin_loop) OVERRIDE { 171 virtual void Run(scoped_refptr<base::MessageLoopProxy> origin_loop) OVERRIDE {
180 ProxyResolver* resolver = executor()->resolver(); 172 ProxyResolver* resolver = executor()->resolver();
181 int rv = resolver->SetPacScript(script_data_, CompletionCallback()); 173 int rv = resolver->SetPacScript(script_data_, CompletionCallback());
182 174
183 DCHECK_NE(rv, ERR_IO_PENDING); 175 DCHECK_NE(rv, ERR_IO_PENDING);
184 origin_loop->PostTask( 176 origin_loop->PostTask(
185 FROM_HERE, 177 FROM_HERE, base::Bind(&SetPacScriptJob::RequestComplete, this, rv));
186 base::Bind(&SetPacScriptJob::RequestComplete, this, rv));
187 } 178 }
188 179
189 protected: 180 protected:
190 virtual ~SetPacScriptJob() {} 181 virtual ~SetPacScriptJob() {}
191 182
192 private: 183 private:
193 // Runs the completion callback on the origin thread. 184 // Runs the completion callback on the origin thread.
194 void RequestComplete(int result_code) { 185 void RequestComplete(int result_code) {
195 // The task may have been cancelled after it was started. 186 // The task may have been cancelled after it was started.
196 if (!was_cancelled() && has_user_callback()) { 187 if (!was_cancelled() && has_user_callback()) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 } 235 }
245 236
246 // Runs on the worker thread. 237 // Runs on the worker thread.
247 virtual void Run(scoped_refptr<base::MessageLoopProxy> origin_loop) OVERRIDE { 238 virtual void Run(scoped_refptr<base::MessageLoopProxy> origin_loop) OVERRIDE {
248 ProxyResolver* resolver = executor()->resolver(); 239 ProxyResolver* resolver = executor()->resolver();
249 int rv = resolver->GetProxyForURL( 240 int rv = resolver->GetProxyForURL(
250 url_, &results_buf_, CompletionCallback(), NULL, net_log_); 241 url_, &results_buf_, CompletionCallback(), NULL, net_log_);
251 DCHECK_NE(rv, ERR_IO_PENDING); 242 DCHECK_NE(rv, ERR_IO_PENDING);
252 243
253 origin_loop->PostTask( 244 origin_loop->PostTask(
254 FROM_HERE, 245 FROM_HERE, base::Bind(&GetProxyForURLJob::QueryComplete, this, rv));
255 base::Bind(&GetProxyForURLJob::QueryComplete, this, rv));
256 } 246 }
257 247
258 protected: 248 protected:
259 virtual ~GetProxyForURLJob() {} 249 virtual ~GetProxyForURLJob() {}
260 250
261 private: 251 private:
262 // Runs the completion callback on the origin thread. 252 // Runs the completion callback on the origin thread.
263 void QueryComplete(int result_code) { 253 void QueryComplete(int result_code) {
264 // The Job may have been cancelled after it was started. 254 // The Job may have been cancelled after it was started.
265 if (!was_cancelled()) { 255 if (!was_cancelled()) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 MultiThreadedProxyResolver::Executor::Executor( 297 MultiThreadedProxyResolver::Executor::Executor(
308 MultiThreadedProxyResolver* coordinator, 298 MultiThreadedProxyResolver* coordinator,
309 ProxyResolver* resolver, 299 ProxyResolver* resolver,
310 int thread_number) 300 int thread_number)
311 : coordinator_(coordinator), 301 : coordinator_(coordinator),
312 thread_number_(thread_number), 302 thread_number_(thread_number),
313 resolver_(resolver) { 303 resolver_(resolver) {
314 DCHECK(coordinator); 304 DCHECK(coordinator);
315 DCHECK(resolver); 305 DCHECK(resolver);
316 // Start up the thread. 306 // Start up the thread.
317 thread_.reset(new base::Thread(base::StringPrintf("PAC thread #%d", 307 thread_.reset(
318 thread_number))); 308 new base::Thread(base::StringPrintf("PAC thread #%d", thread_number)));
319 CHECK(thread_->Start()); 309 CHECK(thread_->Start());
320 } 310 }
321 311
322 void MultiThreadedProxyResolver::Executor::StartJob(Job* job) { 312 void MultiThreadedProxyResolver::Executor::StartJob(Job* job) {
323 DCHECK(!outstanding_job_.get()); 313 DCHECK(!outstanding_job_.get());
324 outstanding_job_ = job; 314 outstanding_job_ = job;
325 315
326 // Run the job. Once it has completed (regardless of whether it was 316 // Run the job. Once it has completed (regardless of whether it was
327 // cancelled), it will invoke OnJobCompleted() on this thread. 317 // cancelled), it will invoke OnJobCompleted() on this thread.
328 job->set_executor(this); 318 job->set_executor(this);
329 job->FinishedWaitingForThread(); 319 job->FinishedWaitingForThread();
330 thread_->message_loop()->PostTask( 320 thread_->message_loop()->PostTask(
331 FROM_HERE, 321 FROM_HERE, base::Bind(&Job::Run, job, base::MessageLoopProxy::current()));
332 base::Bind(&Job::Run, job, base::MessageLoopProxy::current()));
333 } 322 }
334 323
335 void MultiThreadedProxyResolver::Executor::OnJobCompleted(Job* job) { 324 void MultiThreadedProxyResolver::Executor::OnJobCompleted(Job* job) {
336 DCHECK_EQ(job, outstanding_job_.get()); 325 DCHECK_EQ(job, outstanding_job_.get());
337 outstanding_job_ = NULL; 326 outstanding_job_ = NULL;
338 coordinator_->OnExecutorReady(this); 327 coordinator_->OnExecutorReady(this);
339 } 328 }
340 329
341 void MultiThreadedProxyResolver::Executor::Destroy() { 330 void MultiThreadedProxyResolver::Executor::Destroy() {
342 DCHECK(coordinator_); 331 DCHECK(coordinator_);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 DCHECK_GE(max_num_threads, 1u); 374 DCHECK_GE(max_num_threads, 1u);
386 } 375 }
387 376
388 MultiThreadedProxyResolver::~MultiThreadedProxyResolver() { 377 MultiThreadedProxyResolver::~MultiThreadedProxyResolver() {
389 // We will cancel all outstanding requests. 378 // We will cancel all outstanding requests.
390 pending_jobs_.clear(); 379 pending_jobs_.clear();
391 ReleaseAllExecutors(); 380 ReleaseAllExecutors();
392 } 381 }
393 382
394 int MultiThreadedProxyResolver::GetProxyForURL( 383 int MultiThreadedProxyResolver::GetProxyForURL(
395 const GURL& url, ProxyInfo* results, const CompletionCallback& callback, 384 const GURL& url,
396 RequestHandle* request, const BoundNetLog& net_log) { 385 ProxyInfo* results,
386 const CompletionCallback& callback,
387 RequestHandle* request,
388 const BoundNetLog& net_log) {
397 DCHECK(CalledOnValidThread()); 389 DCHECK(CalledOnValidThread());
398 DCHECK(!callback.is_null()); 390 DCHECK(!callback.is_null());
399 DCHECK(current_script_data_.get()) 391 DCHECK(current_script_data_.get())
400 << "Resolver is un-initialized. Must call SetPacScript() first!"; 392 << "Resolver is un-initialized. Must call SetPacScript() first!";
401 393
402 scoped_refptr<GetProxyForURLJob> job( 394 scoped_refptr<GetProxyForURLJob> job(
403 new GetProxyForURLJob(url, results, callback, net_log)); 395 new GetProxyForURLJob(url, results, callback, net_log));
404 396
405 // Completion will be notified through |callback|, unless the caller cancels 397 // Completion will be notified through |callback|, unless the caller cancels
406 // the request using |request|. 398 // the request using |request|.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 LoadState MultiThreadedProxyResolver::GetLoadState(RequestHandle req) const { 446 LoadState MultiThreadedProxyResolver::GetLoadState(RequestHandle req) const {
455 DCHECK(CalledOnValidThread()); 447 DCHECK(CalledOnValidThread());
456 DCHECK(req); 448 DCHECK(req);
457 return LOAD_STATE_RESOLVING_PROXY_FOR_URL; 449 return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
458 } 450 }
459 451
460 void MultiThreadedProxyResolver::CancelSetPacScript() { 452 void MultiThreadedProxyResolver::CancelSetPacScript() {
461 DCHECK(CalledOnValidThread()); 453 DCHECK(CalledOnValidThread());
462 DCHECK_EQ(0u, pending_jobs_.size()); 454 DCHECK_EQ(0u, pending_jobs_.size());
463 DCHECK_EQ(1u, executors_.size()); 455 DCHECK_EQ(1u, executors_.size());
464 DCHECK_EQ(Job::TYPE_SET_PAC_SCRIPT, 456 DCHECK_EQ(Job::TYPE_SET_PAC_SCRIPT, executors_[0]->outstanding_job()->type());
465 executors_[0]->outstanding_job()->type());
466 457
467 // Defensively clear some data which shouldn't be getting used 458 // Defensively clear some data which shouldn't be getting used
468 // anymore. 459 // anymore.
469 current_script_data_ = NULL; 460 current_script_data_ = NULL;
470 461
471 ReleaseAllExecutors(); 462 ReleaseAllExecutors();
472 } 463 }
473 464
474 int MultiThreadedProxyResolver::SetPacScript( 465 int MultiThreadedProxyResolver::SetPacScript(
475 const scoped_refptr<ProxyResolverScriptData>& script_data, 466 const scoped_refptr<ProxyResolverScriptData>& script_data,
476 const CompletionCallback&callback) { 467 const CompletionCallback& callback) {
477 DCHECK(CalledOnValidThread()); 468 DCHECK(CalledOnValidThread());
478 DCHECK(!callback.is_null()); 469 DCHECK(!callback.is_null());
479 470
480 // Save the script details, so we can provision new executors later. 471 // Save the script details, so we can provision new executors later.
481 current_script_data_ = script_data; 472 current_script_data_ = script_data;
482 473
483 // The user should not have any outstanding requests when they call 474 // The user should not have any outstanding requests when they call
484 // SetPacScript(). 475 // SetPacScript().
485 CheckNoOutstandingUserRequests(); 476 CheckNoOutstandingUserRequests();
486 477
487 // Destroy all of the current threads and their proxy resolvers. 478 // Destroy all of the current threads and their proxy resolvers.
488 ReleaseAllExecutors(); 479 ReleaseAllExecutors();
489 480
490 // Provision a new executor, and run the SetPacScript request. On completion 481 // Provision a new executor, and run the SetPacScript request. On completion
491 // notification will be sent through |callback|. 482 // notification will be sent through |callback|.
492 Executor* executor = AddNewExecutor(); 483 Executor* executor = AddNewExecutor();
493 executor->StartJob(new SetPacScriptJob(script_data, callback)); 484 executor->StartJob(new SetPacScriptJob(script_data, callback));
494 return ERR_IO_PENDING; 485 return ERR_IO_PENDING;
495 } 486 }
496 487
497 void MultiThreadedProxyResolver::CheckNoOutstandingUserRequests() const { 488 void MultiThreadedProxyResolver::CheckNoOutstandingUserRequests() const {
498 DCHECK(CalledOnValidThread()); 489 DCHECK(CalledOnValidThread());
499 CHECK_EQ(0u, pending_jobs_.size()); 490 CHECK_EQ(0u, pending_jobs_.size());
500 491
501 for (ExecutorList::const_iterator it = executors_.begin(); 492 for (ExecutorList::const_iterator it = executors_.begin();
502 it != executors_.end(); ++it) { 493 it != executors_.end();
494 ++it) {
503 const Executor* executor = it->get(); 495 const Executor* executor = it->get();
504 Job* job = executor->outstanding_job(); 496 Job* job = executor->outstanding_job();
505 // The "has_user_callback()" is to exclude jobs for which the callback 497 // The "has_user_callback()" is to exclude jobs for which the callback
506 // has already been invoked, or was not user-initiated (as in the case of 498 // has already been invoked, or was not user-initiated (as in the case of
507 // lazy thread provisions). User-initiated jobs may !has_user_callback() 499 // lazy thread provisions). User-initiated jobs may !has_user_callback()
508 // when the callback has already been run. (Since we only clear the 500 // when the callback has already been run. (Since we only clear the
509 // outstanding job AFTER the callback has been invoked, it is possible 501 // outstanding job AFTER the callback has been invoked, it is possible
510 // for a new request to be started from within the callback). 502 // for a new request to be started from within the callback).
511 CHECK(!job || job->was_cancelled() || !job->has_user_callback()); 503 CHECK(!job || job->was_cancelled() || !job->has_user_callback());
512 } 504 }
513 } 505 }
514 506
515 void MultiThreadedProxyResolver::ReleaseAllExecutors() { 507 void MultiThreadedProxyResolver::ReleaseAllExecutors() {
516 DCHECK(CalledOnValidThread()); 508 DCHECK(CalledOnValidThread());
517 for (ExecutorList::iterator it = executors_.begin(); 509 for (ExecutorList::iterator it = executors_.begin(); it != executors_.end();
518 it != executors_.end(); ++it) { 510 ++it) {
519 Executor* executor = it->get(); 511 Executor* executor = it->get();
520 executor->Destroy(); 512 executor->Destroy();
521 } 513 }
522 executors_.clear(); 514 executors_.clear();
523 } 515 }
524 516
525 MultiThreadedProxyResolver::Executor* 517 MultiThreadedProxyResolver::Executor*
526 MultiThreadedProxyResolver::FindIdleExecutor() { 518 MultiThreadedProxyResolver::FindIdleExecutor() {
527 DCHECK(CalledOnValidThread()); 519 DCHECK(CalledOnValidThread());
528 for (ExecutorList::iterator it = executors_.begin(); 520 for (ExecutorList::iterator it = executors_.begin(); it != executors_.end();
529 it != executors_.end(); ++it) { 521 ++it) {
530 Executor* executor = it->get(); 522 Executor* executor = it->get();
531 if (!executor->outstanding_job()) 523 if (!executor->outstanding_job())
532 return executor; 524 return executor;
533 } 525 }
534 return NULL; 526 return NULL;
535 } 527 }
536 528
537 MultiThreadedProxyResolver::Executor* 529 MultiThreadedProxyResolver::Executor*
538 MultiThreadedProxyResolver::AddNewExecutor() { 530 MultiThreadedProxyResolver::AddNewExecutor() {
539 DCHECK(CalledOnValidThread()); 531 DCHECK(CalledOnValidThread());
540 DCHECK_LT(executors_.size(), max_num_threads_); 532 DCHECK_LT(executors_.size(), max_num_threads_);
541 // The "thread number" is used to give the thread a unique name. 533 // The "thread number" is used to give the thread a unique name.
542 int thread_number = executors_.size(); 534 int thread_number = executors_.size();
543 ProxyResolver* resolver = resolver_factory_->CreateProxyResolver(); 535 ProxyResolver* resolver = resolver_factory_->CreateProxyResolver();
544 Executor* executor = new Executor( 536 Executor* executor = new Executor(this, resolver, thread_number);
545 this, resolver, thread_number);
546 executors_.push_back(make_scoped_refptr(executor)); 537 executors_.push_back(make_scoped_refptr(executor));
547 return executor; 538 return executor;
548 } 539 }
549 540
550 void MultiThreadedProxyResolver::OnExecutorReady(Executor* executor) { 541 void MultiThreadedProxyResolver::OnExecutorReady(Executor* executor) {
551 DCHECK(CalledOnValidThread()); 542 DCHECK(CalledOnValidThread());
552 if (pending_jobs_.empty()) 543 if (pending_jobs_.empty())
553 return; 544 return;
554 545
555 // Get the next job to process (FIFO). Transfer it from the pending queue 546 // Get the next job to process (FIFO). Transfer it from the pending queue
556 // to the executor. 547 // to the executor.
557 scoped_refptr<Job> job = pending_jobs_.front(); 548 scoped_refptr<Job> job = pending_jobs_.front();
558 pending_jobs_.pop_front(); 549 pending_jobs_.pop_front();
559 executor->StartJob(job.get()); 550 executor->StartJob(job.get());
560 } 551 }
561 552
562 } // namespace net 553 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698