| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/threading/worker_pool.h" |
| |
| #include "base/bind.h" |
| #include "base/bind_helpers.h" |
| #include "base/location.h" |
| #include "base/message_loop.h" |
| #include "base/test/test_timeouts.h" |
| #include "base/time.h" |
| #include "base/threading/thread_checker_impl.h" |
| #include "base/synchronization/waitable_event.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "testing/platform_test.h" |
| |
| typedef PlatformTest WorkerPoolTest; |
| |
| namespace base { |
| |
| namespace { |
| |
| class PostTaskAndReplyTester |
| : public base::RefCountedThreadSafe<PostTaskAndReplyTester> { |
| public: |
| PostTaskAndReplyTester() : finished_(false), test_event_(false, false) {} |
| |
| void RunTest() { |
| ASSERT_TRUE(thread_checker_.CalledOnValidThread()); |
| WorkerPool::PostTaskAndReply( |
| FROM_HERE, |
| base::Bind(&PostTaskAndReplyTester::OnWorkerThread, this), |
| base::Bind(&PostTaskAndReplyTester::OnOriginalThread, this), |
| false); |
| |
| test_event_.Wait(); |
| } |
| |
| void OnWorkerThread() { |
| // We're not on the original thread. |
| EXPECT_FALSE(thread_checker_.CalledOnValidThread()); |
| |
| test_event_.Signal(); |
| } |
| |
| void OnOriginalThread() { |
| EXPECT_TRUE(thread_checker_.CalledOnValidThread()); |
| finished_ = true; |
| } |
| |
| bool finished() const { |
| return finished_; |
| } |
| |
| private: |
| friend class base::RefCountedThreadSafe<PostTaskAndReplyTester>; |
| ~PostTaskAndReplyTester() {} |
| |
| bool finished_; |
| WaitableEvent test_event_; |
| |
| // The Impl version performs its checks even in release builds. |
| ThreadCheckerImpl thread_checker_; |
| }; |
| |
| } // namespace |
| |
| TEST_F(WorkerPoolTest, PostTask) { |
| WaitableEvent test_event(false, false); |
| WaitableEvent long_test_event(false, false); |
| |
| WorkerPool::PostTask(FROM_HERE, |
| base::Bind(&WaitableEvent::Signal, |
| base::Unretained(&test_event)), |
| false); |
| WorkerPool::PostTask(FROM_HERE, |
| base::Bind(&WaitableEvent::Signal, |
| base::Unretained(&long_test_event)), |
| true); |
| |
| test_event.Wait(); |
| long_test_event.Wait(); |
| } |
| |
| #if defined(OS_WIN) || defined(OS_LINUX) |
| // Flaky on Windows and Linux (http://crbug.com/130337) |
| #define MAYBE_PostTaskAndReply DISABLED_PostTaskAndReply |
| #else |
| #define MAYBE_PostTaskAndReply PostTaskAndReply |
| #endif |
| |
| TEST_F(WorkerPoolTest, MAYBE_PostTaskAndReply) { |
| MessageLoop message_loop; |
| scoped_refptr<PostTaskAndReplyTester> tester(new PostTaskAndReplyTester()); |
| tester->RunTest(); |
| |
| const TimeDelta kMaxDuration = TestTimeouts::tiny_timeout(); |
| TimeTicks start = TimeTicks::Now(); |
| while (!tester->finished() && TimeTicks::Now() - start < kMaxDuration) { |
| #if defined(OS_IOS) |
| // Ensure that the other thread has a chance to run even on a single-core |
| // device. |
| pthread_yield_np(); |
| #endif |
| MessageLoop::current()->RunUntilIdle(); |
| } |
| EXPECT_TRUE(tester->finished()); |
| } |
| |
| } // namespace base |