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 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 SingleThread_UpdatesNetLogWithThreadWait) { | 294 SingleThread_UpdatesNetLogWithThreadWait) { |
302 const size_t kNumThreads = 1u; | 295 const size_t kNumThreads = 1u; |
303 ASSERT_NO_FATAL_FAILURE(Init(kNumThreads)); | 296 ASSERT_NO_FATAL_FAILURE(Init(kNumThreads)); |
304 | 297 |
305 int rv; | 298 int rv; |
306 | 299 |
307 // Block the proxy resolver, so no request can complete. | 300 // Block the proxy resolver, so no request can complete. |
308 factory().resolvers()[0]->Block(); | 301 factory().resolvers()[0]->Block(); |
309 | 302 |
310 // Start request 0. | 303 // Start request 0. |
311 ProxyResolver::RequestHandle request0; | 304 scoped_ptr<ProxyResolver::Request> request0; |
312 TestCompletionCallback callback0; | 305 TestCompletionCallback callback0; |
313 ProxyInfo results0; | 306 ProxyInfo results0; |
314 BoundTestNetLog log0; | 307 BoundTestNetLog log0; |
315 rv = resolver().GetProxyForURL(GURL("http://request0"), &results0, | 308 rv = resolver().GetProxyForURL(GURL("http://request0"), &results0, |
316 callback0.callback(), &request0, log0.bound()); | 309 callback0.callback(), &request0, log0.bound()); |
317 EXPECT_EQ(ERR_IO_PENDING, rv); | 310 EXPECT_EQ(ERR_IO_PENDING, rv); |
318 | 311 |
319 // Start 2 more requests (request1 and request2). | 312 // Start 2 more requests (request1 and request2). |
320 | 313 |
321 TestCompletionCallback callback1; | 314 TestCompletionCallback callback1; |
322 ProxyInfo results1; | 315 ProxyInfo results1; |
323 BoundTestNetLog log1; | 316 BoundTestNetLog log1; |
324 rv = resolver().GetProxyForURL(GURL("http://request1"), &results1, | 317 rv = resolver().GetProxyForURL(GURL("http://request1"), &results1, |
325 callback1.callback(), NULL, log1.bound()); | 318 callback1.callback(), NULL, log1.bound()); |
326 EXPECT_EQ(ERR_IO_PENDING, rv); | 319 EXPECT_EQ(ERR_IO_PENDING, rv); |
327 | 320 |
328 ProxyResolver::RequestHandle request2; | 321 scoped_ptr<ProxyResolver::Request> request2; |
329 TestCompletionCallback callback2; | 322 TestCompletionCallback callback2; |
330 ProxyInfo results2; | 323 ProxyInfo results2; |
331 BoundTestNetLog log2; | 324 BoundTestNetLog log2; |
332 rv = resolver().GetProxyForURL(GURL("http://request2"), &results2, | 325 rv = resolver().GetProxyForURL(GURL("http://request2"), &results2, |
333 callback2.callback(), &request2, log2.bound()); | 326 callback2.callback(), &request2, log2.bound()); |
334 EXPECT_EQ(ERR_IO_PENDING, rv); | 327 EXPECT_EQ(ERR_IO_PENDING, rv); |
335 | 328 |
336 // Unblock the worker thread so the requests can continue running. | 329 // Unblock the worker thread so the requests can continue running. |
337 factory().resolvers()[0]->WaitUntilBlocked(); | 330 factory().resolvers()[0]->WaitUntilBlocked(); |
338 factory().resolvers()[0]->Unblock(); | 331 factory().resolvers()[0]->Unblock(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 TEST_F(MultiThreadedProxyResolverTest, SingleThread_CancelRequest) { | 379 TEST_F(MultiThreadedProxyResolverTest, SingleThread_CancelRequest) { |
387 const size_t kNumThreads = 1u; | 380 const size_t kNumThreads = 1u; |
388 ASSERT_NO_FATAL_FAILURE(Init(kNumThreads)); | 381 ASSERT_NO_FATAL_FAILURE(Init(kNumThreads)); |
389 | 382 |
390 int rv; | 383 int rv; |
391 | 384 |
392 // Block the proxy resolver, so no request can complete. | 385 // Block the proxy resolver, so no request can complete. |
393 factory().resolvers()[0]->Block(); | 386 factory().resolvers()[0]->Block(); |
394 | 387 |
395 // Start request 0. | 388 // Start request 0. |
396 ProxyResolver::RequestHandle request0; | 389 scoped_ptr<ProxyResolver::Request> request0; |
397 TestCompletionCallback callback0; | 390 TestCompletionCallback callback0; |
398 ProxyInfo results0; | 391 ProxyInfo results0; |
399 rv = | 392 rv = |
400 resolver().GetProxyForURL(GURL("http://request0"), &results0, | 393 resolver().GetProxyForURL(GURL("http://request0"), &results0, |
401 callback0.callback(), &request0, BoundNetLog()); | 394 callback0.callback(), &request0, BoundNetLog()); |
402 EXPECT_EQ(ERR_IO_PENDING, rv); | 395 EXPECT_EQ(ERR_IO_PENDING, rv); |
403 | 396 |
404 // Wait until requests 0 reaches the worker thread. | 397 // Wait until requests 0 reaches the worker thread. |
405 factory().resolvers()[0]->WaitUntilBlocked(); | 398 factory().resolvers()[0]->WaitUntilBlocked(); |
406 | 399 |
407 // Start 3 more requests (request1 : request3). | 400 // Start 3 more requests (request1 : request3). |
408 | 401 |
409 TestCompletionCallback callback1; | 402 TestCompletionCallback callback1; |
410 ProxyInfo results1; | 403 ProxyInfo results1; |
411 rv = resolver().GetProxyForURL(GURL("http://request1"), &results1, | 404 rv = resolver().GetProxyForURL(GURL("http://request1"), &results1, |
412 callback1.callback(), NULL, BoundNetLog()); | 405 callback1.callback(), NULL, BoundNetLog()); |
413 EXPECT_EQ(ERR_IO_PENDING, rv); | 406 EXPECT_EQ(ERR_IO_PENDING, rv); |
414 | 407 |
415 ProxyResolver::RequestHandle request2; | 408 scoped_ptr<ProxyResolver::Request> request2; |
416 TestCompletionCallback callback2; | 409 TestCompletionCallback callback2; |
417 ProxyInfo results2; | 410 ProxyInfo results2; |
418 rv = | 411 rv = |
419 resolver().GetProxyForURL(GURL("http://request2"), &results2, | 412 resolver().GetProxyForURL(GURL("http://request2"), &results2, |
420 callback2.callback(), &request2, BoundNetLog()); | 413 callback2.callback(), &request2, BoundNetLog()); |
421 EXPECT_EQ(ERR_IO_PENDING, rv); | 414 EXPECT_EQ(ERR_IO_PENDING, rv); |
422 | 415 |
423 TestCompletionCallback callback3; | 416 TestCompletionCallback callback3; |
424 ProxyInfo results3; | 417 ProxyInfo results3; |
425 rv = resolver().GetProxyForURL(GURL("http://request3"), &results3, | 418 rv = resolver().GetProxyForURL(GURL("http://request3"), &results3, |
426 callback3.callback(), NULL, BoundNetLog()); | 419 callback3.callback(), NULL, BoundNetLog()); |
427 EXPECT_EQ(ERR_IO_PENDING, rv); | 420 EXPECT_EQ(ERR_IO_PENDING, rv); |
428 | 421 |
429 // Cancel request0 (inprogress) and request2 (pending). | 422 // Cancel request0 (inprogress) and request2 (pending). |
430 resolver().CancelRequest(request0); | 423 request0.reset(); |
431 resolver().CancelRequest(request2); | 424 request2.reset(); |
432 | 425 |
433 // Unblock the worker thread so the requests can continue running. | 426 // Unblock the worker thread so the requests can continue running. |
434 factory().resolvers()[0]->Unblock(); | 427 factory().resolvers()[0]->Unblock(); |
435 | 428 |
436 // Wait for requests 1 and 3 to finish. | 429 // Wait for requests 1 and 3 to finish. |
437 | 430 |
438 rv = callback1.WaitForResult(); | 431 rv = callback1.WaitForResult(); |
439 EXPECT_EQ(1, rv); | 432 EXPECT_EQ(1, rv); |
440 EXPECT_EQ("PROXY request1:80", results1.ToPacString()); | 433 EXPECT_EQ("PROXY request1:80", results1.ToPacString()); |
441 | 434 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 ASSERT_NO_FATAL_FAILURE(Init(kNumThreads)); | 508 ASSERT_NO_FATAL_FAILURE(Init(kNumThreads)); |
516 | 509 |
517 // Verify that it reaches the synchronous resolver. | 510 // Verify that it reaches the synchronous resolver. |
518 // One thread has been provisioned (i.e. one ProxyResolver was created). | 511 // One thread has been provisioned (i.e. one ProxyResolver was created). |
519 ASSERT_EQ(1u, factory().resolvers().size()); | 512 ASSERT_EQ(1u, factory().resolvers().size()); |
520 | 513 |
521 const int kNumRequests = 8; | 514 const int kNumRequests = 8; |
522 int rv; | 515 int rv; |
523 TestCompletionCallback callback[kNumRequests]; | 516 TestCompletionCallback callback[kNumRequests]; |
524 ProxyInfo results[kNumRequests]; | 517 ProxyInfo results[kNumRequests]; |
525 ProxyResolver::RequestHandle request[kNumRequests]; | 518 scoped_ptr<ProxyResolver::Request> request[kNumRequests]; |
526 | 519 |
527 // Start request 0 -- this should run on thread 0 as there is nothing else | 520 // Start request 0 -- this should run on thread 0 as there is nothing else |
528 // going on right now. | 521 // going on right now. |
529 rv = resolver().GetProxyForURL(GURL("http://request0"), &results[0], | 522 rv = resolver().GetProxyForURL(GURL("http://request0"), &results[0], |
530 callback[0].callback(), &request[0], | 523 callback[0].callback(), &request[0], |
531 BoundNetLog()); | 524 BoundNetLog()); |
532 EXPECT_EQ(ERR_IO_PENDING, rv); | 525 EXPECT_EQ(ERR_IO_PENDING, rv); |
533 | 526 |
534 // Wait for request 0 to finish. | 527 // Wait for request 0 to finish. |
535 rv = callback[0].WaitForResult(); | 528 rv = callback[0].WaitForResult(); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 BoundNetLog()); | 583 BoundNetLog()); |
591 EXPECT_EQ(ERR_IO_PENDING, rv); | 584 EXPECT_EQ(ERR_IO_PENDING, rv); |
592 rv = resolver().GetProxyForURL(GURL("http://request6"), &results[6], | 585 rv = resolver().GetProxyForURL(GURL("http://request6"), &results[6], |
593 callback[6].callback(), &request[6], | 586 callback[6].callback(), &request[6], |
594 BoundNetLog()); | 587 BoundNetLog()); |
595 EXPECT_EQ(ERR_IO_PENDING, rv); | 588 EXPECT_EQ(ERR_IO_PENDING, rv); |
596 rv = resolver().GetProxyForURL(GURL("http://request7"), &results[7], | 589 rv = resolver().GetProxyForURL(GURL("http://request7"), &results[7], |
597 callback[7].callback(), &request[7], | 590 callback[7].callback(), &request[7], |
598 BoundNetLog()); | 591 BoundNetLog()); |
599 EXPECT_EQ(ERR_IO_PENDING, rv); | 592 EXPECT_EQ(ERR_IO_PENDING, rv); |
600 resolver().CancelRequest(request[5]); | 593 request[5].reset(); |
601 resolver().CancelRequest(request[6]); | 594 request[6].reset(); |
602 | 595 |
603 EXPECT_EQ(2, callback[7].WaitForResult()); | 596 EXPECT_EQ(2, callback[7].WaitForResult()); |
604 | 597 |
605 // Check that the cancelled requests never invoked their callback. | 598 // Check that the cancelled requests never invoked their callback. |
606 EXPECT_FALSE(callback[5].have_result()); | 599 EXPECT_FALSE(callback[5].have_result()); |
607 EXPECT_FALSE(callback[6].have_result()); | 600 EXPECT_FALSE(callback[6].have_result()); |
608 | 601 |
609 // Unblock the first two threads and wait for their requests to complete. | 602 // Unblock the first two threads and wait for their requests to complete. |
610 factory().resolvers()[0]->Unblock(); | 603 factory().resolvers()[0]->Unblock(); |
611 factory().resolvers()[1]->Unblock(); | 604 factory().resolvers()[1]->Unblock(); |
(...skipping 15 matching lines...) Expand all Loading... |
627 int rv; | 620 int rv; |
628 | 621 |
629 // One thread has been provisioned (i.e. one ProxyResolver was created). | 622 // One thread has been provisioned (i.e. one ProxyResolver was created). |
630 ASSERT_EQ(1u, factory().resolvers().size()); | 623 ASSERT_EQ(1u, factory().resolvers().size()); |
631 EXPECT_EQ(ASCIIToUTF16("pac script bytes"), | 624 EXPECT_EQ(ASCIIToUTF16("pac script bytes"), |
632 factory().script_data()[0]->utf16()); | 625 factory().script_data()[0]->utf16()); |
633 | 626 |
634 const int kNumRequests = 4; | 627 const int kNumRequests = 4; |
635 TestCompletionCallback callback[kNumRequests]; | 628 TestCompletionCallback callback[kNumRequests]; |
636 ProxyInfo results[kNumRequests]; | 629 ProxyInfo results[kNumRequests]; |
637 ProxyResolver::RequestHandle request[kNumRequests]; | 630 scoped_ptr<ProxyResolver::Request> request[kNumRequests]; |
638 | 631 |
639 // Start a request that will block the first thread. | 632 // Start a request that will block the first thread. |
640 | 633 |
641 factory().resolvers()[0]->Block(); | 634 factory().resolvers()[0]->Block(); |
642 | 635 |
643 rv = resolver().GetProxyForURL(GURL("http://request0"), &results[0], | 636 rv = resolver().GetProxyForURL(GURL("http://request0"), &results[0], |
644 callback[0].callback(), &request[0], | 637 callback[0].callback(), &request[0], |
645 BoundNetLog()); | 638 BoundNetLog()); |
646 | 639 |
647 EXPECT_EQ(ERR_IO_PENDING, rv); | 640 EXPECT_EQ(ERR_IO_PENDING, rv); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
772 } | 765 } |
773 // The factory destructor will block until the worker thread stops, but it may | 766 // The factory destructor will block until the worker thread stops, but it may |
774 // post tasks to the origin message loop which are still pending. Run them | 767 // post tasks to the origin message loop which are still pending. Run them |
775 // now to ensure it works as expected. | 768 // now to ensure it works as expected. |
776 base::RunLoop().RunUntilIdle(); | 769 base::RunLoop().RunUntilIdle(); |
777 } | 770 } |
778 | 771 |
779 } // namespace | 772 } // namespace |
780 | 773 |
781 } // namespace net | 774 } // namespace net |
OLD | NEW |