| 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 <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 // - returns a single-item proxy list with the query's host. | 38 // - returns a single-item proxy list with the query's host. |
| 39 class MockProxyResolver : public ProxyResolver { | 39 class MockProxyResolver : public ProxyResolver { |
| 40 public: | 40 public: |
| 41 MockProxyResolver() | 41 MockProxyResolver() |
| 42 : worker_loop_(base::MessageLoop::current()), request_count_(0) {} | 42 : worker_loop_(base::MessageLoop::current()), request_count_(0) {} |
| 43 | 43 |
| 44 // ProxyResolver implementation. | 44 // ProxyResolver implementation. |
| 45 int GetProxyForURL(const GURL& query_url, | 45 int GetProxyForURL(const GURL& query_url, |
| 46 ProxyInfo* results, | 46 ProxyInfo* results, |
| 47 const CompletionCallback& callback, | 47 const CompletionCallback& callback, |
| 48 RequestHandle* request, | 48 scoped_ptr<Request>* request, |
| 49 const BoundNetLog& net_log) override { | 49 const BoundNetLog& net_log) override { |
| 50 if (resolve_latency_ != base::TimeDelta()) | 50 if (resolve_latency_ != base::TimeDelta()) |
| 51 base::PlatformThread::Sleep(resolve_latency_); | 51 base::PlatformThread::Sleep(resolve_latency_); |
| 52 | 52 |
| 53 CheckIsOnWorkerThread(); | 53 CheckIsOnWorkerThread(); |
| 54 | 54 |
| 55 EXPECT_TRUE(callback.is_null()); | 55 EXPECT_TRUE(callback.is_null()); |
| 56 EXPECT_TRUE(request == NULL); | 56 EXPECT_TRUE(request == NULL); |
| 57 | 57 |
| 58 // Write something into |net_log| (doesn't really have any meaning.) | 58 // Write something into |net_log| (doesn't really have any meaning.) |
| 59 net_log.BeginEvent(NetLog::TYPE_PAC_JAVASCRIPT_ALERT); | 59 net_log.BeginEvent(NetLog::TYPE_PAC_JAVASCRIPT_ALERT); |
| 60 | 60 |
| 61 results->UseNamedProxy(query_url.host()); | 61 results->UseNamedProxy(query_url.host()); |
| 62 | 62 |
| 63 // Return a success code which represents the request's order. | 63 // Return a success code which represents the request's order. |
| 64 return request_count_++; | 64 return request_count_++; |
| 65 } | 65 } |
| 66 | 66 |
| 67 void CancelRequest(RequestHandle request) override { NOTREACHED(); } | |
| 68 | |
| 69 LoadState GetLoadState(RequestHandle request) const override { | |
| 70 NOTREACHED(); | |
| 71 return LOAD_STATE_IDLE; | |
| 72 } | |
| 73 | |
| 74 int request_count() const { return request_count_; } | 67 int request_count() const { return request_count_; } |
| 75 | 68 |
| 76 void SetResolveLatency(base::TimeDelta latency) { | 69 void SetResolveLatency(base::TimeDelta latency) { |
| 77 resolve_latency_ = latency; | 70 resolve_latency_ = latency; |
| 78 } | 71 } |
| 79 | 72 |
| 80 private: | 73 private: |
| 81 void CheckIsOnWorkerThread() { | 74 void CheckIsOnWorkerThread() { |
| 82 EXPECT_EQ(base::MessageLoop::current(), worker_loop_); | 75 EXPECT_EQ(base::MessageLoop::current(), worker_loop_); |
| 83 } | 76 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 112 unblocked_.Signal(); | 105 unblocked_.Signal(); |
| 113 } | 106 } |
| 114 | 107 |
| 115 void WaitUntilBlocked() { | 108 void WaitUntilBlocked() { |
| 116 blocked_.Wait(); | 109 blocked_.Wait(); |
| 117 } | 110 } |
| 118 | 111 |
| 119 int GetProxyForURL(const GURL& query_url, | 112 int GetProxyForURL(const GURL& query_url, |
| 120 ProxyInfo* results, | 113 ProxyInfo* results, |
| 121 const CompletionCallback& callback, | 114 const CompletionCallback& callback, |
| 122 RequestHandle* request, | 115 scoped_ptr<Request>* request, |
| 123 const BoundNetLog& net_log) override { | 116 const BoundNetLog& net_log) override { |
| 124 if (should_block_) { | 117 if (should_block_) { |
| 125 blocked_.Signal(); | 118 blocked_.Signal(); |
| 126 unblocked_.Wait(); | 119 unblocked_.Wait(); |
| 127 } | 120 } |
| 128 | 121 |
| 129 return MockProxyResolver::GetProxyForURL( | 122 return MockProxyResolver::GetProxyForURL( |
| 130 query_url, results, callback, request, net_log); | 123 query_url, results, callback, request, net_log); |
| 131 } | 124 } |
| 132 | 125 |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 SingleThread_UpdatesNetLogWithThreadWait) { | 299 SingleThread_UpdatesNetLogWithThreadWait) { |
| 307 const size_t kNumThreads = 1u; | 300 const size_t kNumThreads = 1u; |
| 308 ASSERT_NO_FATAL_FAILURE(Init(kNumThreads)); | 301 ASSERT_NO_FATAL_FAILURE(Init(kNumThreads)); |
| 309 | 302 |
| 310 int rv; | 303 int rv; |
| 311 | 304 |
| 312 // Block the proxy resolver, so no request can complete. | 305 // Block the proxy resolver, so no request can complete. |
| 313 factory().resolvers()[0]->Block(); | 306 factory().resolvers()[0]->Block(); |
| 314 | 307 |
| 315 // Start request 0. | 308 // Start request 0. |
| 316 ProxyResolver::RequestHandle request0; | 309 scoped_ptr<ProxyResolver::Request> request0; |
| 317 TestCompletionCallback callback0; | 310 TestCompletionCallback callback0; |
| 318 ProxyInfo results0; | 311 ProxyInfo results0; |
| 319 BoundTestNetLog log0; | 312 BoundTestNetLog log0; |
| 320 rv = resolver().GetProxyForURL(GURL("http://request0"), &results0, | 313 rv = resolver().GetProxyForURL(GURL("http://request0"), &results0, |
| 321 callback0.callback(), &request0, log0.bound()); | 314 callback0.callback(), &request0, log0.bound()); |
| 322 EXPECT_EQ(ERR_IO_PENDING, rv); | 315 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 323 | 316 |
| 324 // Start 2 more requests (request1 and request2). | 317 // Start 2 more requests (request1 and request2). |
| 325 | 318 |
| 326 TestCompletionCallback callback1; | 319 TestCompletionCallback callback1; |
| 327 ProxyInfo results1; | 320 ProxyInfo results1; |
| 328 BoundTestNetLog log1; | 321 BoundTestNetLog log1; |
| 329 rv = resolver().GetProxyForURL(GURL("http://request1"), &results1, | 322 rv = resolver().GetProxyForURL(GURL("http://request1"), &results1, |
| 330 callback1.callback(), NULL, log1.bound()); | 323 callback1.callback(), NULL, log1.bound()); |
| 331 EXPECT_EQ(ERR_IO_PENDING, rv); | 324 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 332 | 325 |
| 333 ProxyResolver::RequestHandle request2; | 326 scoped_ptr<ProxyResolver::Request> request2; |
| 334 TestCompletionCallback callback2; | 327 TestCompletionCallback callback2; |
| 335 ProxyInfo results2; | 328 ProxyInfo results2; |
| 336 BoundTestNetLog log2; | 329 BoundTestNetLog log2; |
| 337 rv = resolver().GetProxyForURL(GURL("http://request2"), &results2, | 330 rv = resolver().GetProxyForURL(GURL("http://request2"), &results2, |
| 338 callback2.callback(), &request2, log2.bound()); | 331 callback2.callback(), &request2, log2.bound()); |
| 339 EXPECT_EQ(ERR_IO_PENDING, rv); | 332 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 340 | 333 |
| 341 // Unblock the worker thread so the requests can continue running. | 334 // Unblock the worker thread so the requests can continue running. |
| 342 factory().resolvers()[0]->WaitUntilBlocked(); | 335 factory().resolvers()[0]->WaitUntilBlocked(); |
| 343 factory().resolvers()[0]->Unblock(); | 336 factory().resolvers()[0]->Unblock(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 TEST_F(MultiThreadedProxyResolverTest, SingleThread_CancelRequest) { | 384 TEST_F(MultiThreadedProxyResolverTest, SingleThread_CancelRequest) { |
| 392 const size_t kNumThreads = 1u; | 385 const size_t kNumThreads = 1u; |
| 393 ASSERT_NO_FATAL_FAILURE(Init(kNumThreads)); | 386 ASSERT_NO_FATAL_FAILURE(Init(kNumThreads)); |
| 394 | 387 |
| 395 int rv; | 388 int rv; |
| 396 | 389 |
| 397 // Block the proxy resolver, so no request can complete. | 390 // Block the proxy resolver, so no request can complete. |
| 398 factory().resolvers()[0]->Block(); | 391 factory().resolvers()[0]->Block(); |
| 399 | 392 |
| 400 // Start request 0. | 393 // Start request 0. |
| 401 ProxyResolver::RequestHandle request0; | 394 scoped_ptr<ProxyResolver::Request> request0; |
| 402 TestCompletionCallback callback0; | 395 TestCompletionCallback callback0; |
| 403 ProxyInfo results0; | 396 ProxyInfo results0; |
| 404 rv = | 397 rv = |
| 405 resolver().GetProxyForURL(GURL("http://request0"), &results0, | 398 resolver().GetProxyForURL(GURL("http://request0"), &results0, |
| 406 callback0.callback(), &request0, BoundNetLog()); | 399 callback0.callback(), &request0, BoundNetLog()); |
| 407 EXPECT_EQ(ERR_IO_PENDING, rv); | 400 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 408 | 401 |
| 409 // Wait until requests 0 reaches the worker thread. | 402 // Wait until requests 0 reaches the worker thread. |
| 410 factory().resolvers()[0]->WaitUntilBlocked(); | 403 factory().resolvers()[0]->WaitUntilBlocked(); |
| 411 | 404 |
| 412 // Start 3 more requests (request1 : request3). | 405 // Start 3 more requests (request1 : request3). |
| 413 | 406 |
| 414 TestCompletionCallback callback1; | 407 TestCompletionCallback callback1; |
| 415 ProxyInfo results1; | 408 ProxyInfo results1; |
| 416 rv = resolver().GetProxyForURL(GURL("http://request1"), &results1, | 409 rv = resolver().GetProxyForURL(GURL("http://request1"), &results1, |
| 417 callback1.callback(), NULL, BoundNetLog()); | 410 callback1.callback(), NULL, BoundNetLog()); |
| 418 EXPECT_EQ(ERR_IO_PENDING, rv); | 411 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 419 | 412 |
| 420 ProxyResolver::RequestHandle request2; | 413 scoped_ptr<ProxyResolver::Request> request2; |
| 421 TestCompletionCallback callback2; | 414 TestCompletionCallback callback2; |
| 422 ProxyInfo results2; | 415 ProxyInfo results2; |
| 423 rv = | 416 rv = |
| 424 resolver().GetProxyForURL(GURL("http://request2"), &results2, | 417 resolver().GetProxyForURL(GURL("http://request2"), &results2, |
| 425 callback2.callback(), &request2, BoundNetLog()); | 418 callback2.callback(), &request2, BoundNetLog()); |
| 426 EXPECT_EQ(ERR_IO_PENDING, rv); | 419 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 427 | 420 |
| 428 TestCompletionCallback callback3; | 421 TestCompletionCallback callback3; |
| 429 ProxyInfo results3; | 422 ProxyInfo results3; |
| 430 rv = resolver().GetProxyForURL(GURL("http://request3"), &results3, | 423 rv = resolver().GetProxyForURL(GURL("http://request3"), &results3, |
| 431 callback3.callback(), NULL, BoundNetLog()); | 424 callback3.callback(), NULL, BoundNetLog()); |
| 432 EXPECT_EQ(ERR_IO_PENDING, rv); | 425 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 433 | 426 |
| 434 // Cancel request0 (inprogress) and request2 (pending). | 427 // Cancel request0 (inprogress) and request2 (pending). |
| 435 resolver().CancelRequest(request0); | 428 request0.reset(); |
| 436 resolver().CancelRequest(request2); | 429 request2.reset(); |
| 437 | 430 |
| 438 // Unblock the worker thread so the requests can continue running. | 431 // Unblock the worker thread so the requests can continue running. |
| 439 factory().resolvers()[0]->Unblock(); | 432 factory().resolvers()[0]->Unblock(); |
| 440 | 433 |
| 441 // Wait for requests 1 and 3 to finish. | 434 // Wait for requests 1 and 3 to finish. |
| 442 | 435 |
| 443 rv = callback1.WaitForResult(); | 436 rv = callback1.WaitForResult(); |
| 444 EXPECT_EQ(1, rv); | 437 EXPECT_EQ(1, rv); |
| 445 EXPECT_EQ("PROXY request1:80", results1.ToPacString()); | 438 EXPECT_EQ("PROXY request1:80", results1.ToPacString()); |
| 446 | 439 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 ASSERT_NO_FATAL_FAILURE(Init(kNumThreads)); | 513 ASSERT_NO_FATAL_FAILURE(Init(kNumThreads)); |
| 521 | 514 |
| 522 // Verify that it reaches the synchronous resolver. | 515 // Verify that it reaches the synchronous resolver. |
| 523 // One thread has been provisioned (i.e. one ProxyResolver was created). | 516 // One thread has been provisioned (i.e. one ProxyResolver was created). |
| 524 ASSERT_EQ(1u, factory().resolvers().size()); | 517 ASSERT_EQ(1u, factory().resolvers().size()); |
| 525 | 518 |
| 526 const int kNumRequests = 8; | 519 const int kNumRequests = 8; |
| 527 int rv; | 520 int rv; |
| 528 TestCompletionCallback callback[kNumRequests]; | 521 TestCompletionCallback callback[kNumRequests]; |
| 529 ProxyInfo results[kNumRequests]; | 522 ProxyInfo results[kNumRequests]; |
| 530 ProxyResolver::RequestHandle request[kNumRequests]; | 523 scoped_ptr<ProxyResolver::Request> request[kNumRequests]; |
| 531 | 524 |
| 532 // Start request 0 -- this should run on thread 0 as there is nothing else | 525 // Start request 0 -- this should run on thread 0 as there is nothing else |
| 533 // going on right now. | 526 // going on right now. |
| 534 rv = resolver().GetProxyForURL(GURL("http://request0"), &results[0], | 527 rv = resolver().GetProxyForURL(GURL("http://request0"), &results[0], |
| 535 callback[0].callback(), &request[0], | 528 callback[0].callback(), &request[0], |
| 536 BoundNetLog()); | 529 BoundNetLog()); |
| 537 EXPECT_EQ(ERR_IO_PENDING, rv); | 530 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 538 | 531 |
| 539 // Wait for request 0 to finish. | 532 // Wait for request 0 to finish. |
| 540 rv = callback[0].WaitForResult(); | 533 rv = callback[0].WaitForResult(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 BoundNetLog()); | 588 BoundNetLog()); |
| 596 EXPECT_EQ(ERR_IO_PENDING, rv); | 589 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 597 rv = resolver().GetProxyForURL(GURL("http://request6"), &results[6], | 590 rv = resolver().GetProxyForURL(GURL("http://request6"), &results[6], |
| 598 callback[6].callback(), &request[6], | 591 callback[6].callback(), &request[6], |
| 599 BoundNetLog()); | 592 BoundNetLog()); |
| 600 EXPECT_EQ(ERR_IO_PENDING, rv); | 593 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 601 rv = resolver().GetProxyForURL(GURL("http://request7"), &results[7], | 594 rv = resolver().GetProxyForURL(GURL("http://request7"), &results[7], |
| 602 callback[7].callback(), &request[7], | 595 callback[7].callback(), &request[7], |
| 603 BoundNetLog()); | 596 BoundNetLog()); |
| 604 EXPECT_EQ(ERR_IO_PENDING, rv); | 597 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 605 resolver().CancelRequest(request[5]); | 598 request[5].reset(); |
| 606 resolver().CancelRequest(request[6]); | 599 request[6].reset(); |
| 607 | 600 |
| 608 EXPECT_EQ(2, callback[7].WaitForResult()); | 601 EXPECT_EQ(2, callback[7].WaitForResult()); |
| 609 | 602 |
| 610 // Check that the cancelled requests never invoked their callback. | 603 // Check that the cancelled requests never invoked their callback. |
| 611 EXPECT_FALSE(callback[5].have_result()); | 604 EXPECT_FALSE(callback[5].have_result()); |
| 612 EXPECT_FALSE(callback[6].have_result()); | 605 EXPECT_FALSE(callback[6].have_result()); |
| 613 | 606 |
| 614 // Unblock the first two threads and wait for their requests to complete. | 607 // Unblock the first two threads and wait for their requests to complete. |
| 615 factory().resolvers()[0]->Unblock(); | 608 factory().resolvers()[0]->Unblock(); |
| 616 factory().resolvers()[1]->Unblock(); | 609 factory().resolvers()[1]->Unblock(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 632 int rv; | 625 int rv; |
| 633 | 626 |
| 634 // One thread has been provisioned (i.e. one ProxyResolver was created). | 627 // One thread has been provisioned (i.e. one ProxyResolver was created). |
| 635 ASSERT_EQ(1u, factory().resolvers().size()); | 628 ASSERT_EQ(1u, factory().resolvers().size()); |
| 636 EXPECT_EQ(ASCIIToUTF16("pac script bytes"), | 629 EXPECT_EQ(ASCIIToUTF16("pac script bytes"), |
| 637 factory().script_data()[0]->utf16()); | 630 factory().script_data()[0]->utf16()); |
| 638 | 631 |
| 639 const int kNumRequests = 4; | 632 const int kNumRequests = 4; |
| 640 TestCompletionCallback callback[kNumRequests]; | 633 TestCompletionCallback callback[kNumRequests]; |
| 641 ProxyInfo results[kNumRequests]; | 634 ProxyInfo results[kNumRequests]; |
| 642 ProxyResolver::RequestHandle request[kNumRequests]; | 635 scoped_ptr<ProxyResolver::Request> request[kNumRequests]; |
| 643 | 636 |
| 644 // Start a request that will block the first thread. | 637 // Start a request that will block the first thread. |
| 645 | 638 |
| 646 factory().resolvers()[0]->Block(); | 639 factory().resolvers()[0]->Block(); |
| 647 | 640 |
| 648 rv = resolver().GetProxyForURL(GURL("http://request0"), &results[0], | 641 rv = resolver().GetProxyForURL(GURL("http://request0"), &results[0], |
| 649 callback[0].callback(), &request[0], | 642 callback[0].callback(), &request[0], |
| 650 BoundNetLog()); | 643 BoundNetLog()); |
| 651 | 644 |
| 652 EXPECT_EQ(ERR_IO_PENDING, rv); | 645 EXPECT_EQ(ERR_IO_PENDING, rv); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 } | 770 } |
| 778 // The factory destructor will block until the worker thread stops, but it may | 771 // The factory destructor will block until the worker thread stops, but it may |
| 779 // post tasks to the origin message loop which are still pending. Run them | 772 // post tasks to the origin message loop which are still pending. Run them |
| 780 // now to ensure it works as expected. | 773 // now to ensure it works as expected. |
| 781 base::RunLoop().RunUntilIdle(); | 774 base::RunLoop().RunUntilIdle(); |
| 782 } | 775 } |
| 783 | 776 |
| 784 } // namespace | 777 } // namespace |
| 785 | 778 |
| 786 } // namespace net | 779 } // namespace net |
| OLD | NEW |