Home | History | Annotate | Download | only in threading
      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