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