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