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 3 // found in the LICENSE file. 4 5 #include "base/threading/worker_pool.h" 6 7 #include "base/bind.h" 8 #include "base/bind_helpers.h" 9 #include "base/location.h" 10 #include "base/message_loop/message_loop.h" 11 #include "base/run_loop.h" 12 #include "base/synchronization/waitable_event.h" 13 #include "base/test/test_timeouts.h" 14 #include "base/threading/thread_checker_impl.h" 15 #include "base/time/time.h" 16 #include "testing/gtest/include/gtest/gtest.h" 17 #include "testing/platform_test.h" 18 19 typedef PlatformTest WorkerPoolTest; 20 21 namespace base { 22 23 namespace { 24 25 class PostTaskAndReplyTester 26 : public base::RefCountedThreadSafe<PostTaskAndReplyTester> { 27 public: 28 PostTaskAndReplyTester() : finished_(false), test_event_(false, false) {} 29 30 void RunTest() { 31 ASSERT_TRUE(thread_checker_.CalledOnValidThread()); 32 WorkerPool::PostTaskAndReply( 33 FROM_HERE, 34 base::Bind(&PostTaskAndReplyTester::OnWorkerThread, this), 35 base::Bind(&PostTaskAndReplyTester::OnOriginalThread, this), 36 false); 37 38 test_event_.Wait(); 39 } 40 41 void OnWorkerThread() { 42 // We're not on the original thread. 43 EXPECT_FALSE(thread_checker_.CalledOnValidThread()); 44 45 test_event_.Signal(); 46 } 47 48 void OnOriginalThread() { 49 EXPECT_TRUE(thread_checker_.CalledOnValidThread()); 50 finished_ = true; 51 } 52 53 bool finished() const { 54 return finished_; 55 } 56 57 private: 58 friend class base::RefCountedThreadSafe<PostTaskAndReplyTester>; 59 ~PostTaskAndReplyTester() {} 60 61 bool finished_; 62 WaitableEvent test_event_; 63 64 // The Impl version performs its checks even in release builds. 65 ThreadCheckerImpl thread_checker_; 66 }; 67 68 } // namespace 69 70 TEST_F(WorkerPoolTest, PostTask) { 71 WaitableEvent test_event(false, false); 72 WaitableEvent long_test_event(false, false); 73 74 WorkerPool::PostTask(FROM_HERE, 75 base::Bind(&WaitableEvent::Signal, 76 base::Unretained(&test_event)), 77 false); 78 WorkerPool::PostTask(FROM_HERE, 79 base::Bind(&WaitableEvent::Signal, 80 base::Unretained(&long_test_event)), 81 true); 82 83 test_event.Wait(); 84 long_test_event.Wait(); 85 } 86 87 #if defined(OS_WIN) || defined(OS_LINUX) 88 // Flaky on Windows and Linux (http://crbug.com/130337) 89 #define MAYBE_PostTaskAndReply DISABLED_PostTaskAndReply 90 #else 91 #define MAYBE_PostTaskAndReply PostTaskAndReply 92 #endif 93 94 TEST_F(WorkerPoolTest, MAYBE_PostTaskAndReply) { 95 MessageLoop message_loop; 96 scoped_refptr<PostTaskAndReplyTester> tester(new PostTaskAndReplyTester()); 97 tester->RunTest(); 98 99 const TimeDelta kMaxDuration = TestTimeouts::tiny_timeout(); 100 TimeTicks start = TimeTicks::Now(); 101 while (!tester->finished() && TimeTicks::Now() - start < kMaxDuration) { 102 #if defined(OS_IOS) 103 // Ensure that the other thread has a chance to run even on a single-core 104 // device. 105 pthread_yield_np(); 106 #endif 107 RunLoop().RunUntilIdle(); 108 } 109 EXPECT_TRUE(tester->finished()); 110 } 111 112 } // namespace base 113