worker_pool_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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/run_loop.h"
12#include "base/test/test_timeouts.h"
13#include "base/time.h"
14#include "base/threading/thread_checker_impl.h"
15#include "base/synchronization/waitable_event.h"
16#include "testing/gtest/include/gtest/gtest.h"
17#include "testing/platform_test.h"
18
19typedef PlatformTest WorkerPoolTest;
20
21namespace base {
22
23namespace {
24
25class 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
70TEST_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
94TEST_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