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