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