Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / base / threading / simple_thread_unittest.cc
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/atomic_sequence_num.h"
6 #include "base/strings/string_number_conversions.h"
7 #include "base/synchronization/waitable_event.h"
8 #include "base/threading/simple_thread.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 namespace base {
12
13 namespace {
14
15 class SetIntRunner : public DelegateSimpleThread::Delegate {
16  public:
17   SetIntRunner(int* ptr, int val) : ptr_(ptr), val_(val) { }
18   ~SetIntRunner() override {}
19
20   void Run() override { *ptr_ = val_; }
21
22  private:
23   int* ptr_;
24   int val_;
25 };
26
27 class WaitEventRunner : public DelegateSimpleThread::Delegate {
28  public:
29   explicit WaitEventRunner(WaitableEvent* event) : event_(event) { }
30   ~WaitEventRunner() override {}
31
32   void Run() override {
33     EXPECT_FALSE(event_->IsSignaled());
34     event_->Signal();
35     EXPECT_TRUE(event_->IsSignaled());
36   }
37  private:
38   WaitableEvent* event_;
39 };
40
41 class SeqRunner : public DelegateSimpleThread::Delegate {
42  public:
43   explicit SeqRunner(AtomicSequenceNumber* seq) : seq_(seq) { }
44   void Run() override { seq_->GetNext(); }
45
46  private:
47   AtomicSequenceNumber* seq_;
48 };
49
50 // We count up on a sequence number, firing on the event when we've hit our
51 // expected amount, otherwise we wait on the event.  This will ensure that we
52 // have all threads outstanding until we hit our expected thread pool size.
53 class VerifyPoolRunner : public DelegateSimpleThread::Delegate {
54  public:
55   VerifyPoolRunner(AtomicSequenceNumber* seq,
56                    int total, WaitableEvent* event)
57       : seq_(seq), total_(total), event_(event) { }
58
59   void Run() override {
60     if (seq_->GetNext() == total_) {
61       event_->Signal();
62     } else {
63       event_->Wait();
64     }
65   }
66
67  private:
68   AtomicSequenceNumber* seq_;
69   int total_;
70   WaitableEvent* event_;
71 };
72
73 }  // namespace
74
75 TEST(SimpleThreadTest, CreateAndJoin) {
76   int stack_int = 0;
77
78   SetIntRunner runner(&stack_int, 7);
79   EXPECT_EQ(0, stack_int);
80
81   DelegateSimpleThread thread(&runner, "int_setter");
82   EXPECT_FALSE(thread.HasBeenStarted());
83   EXPECT_FALSE(thread.HasBeenJoined());
84   EXPECT_EQ(0, stack_int);
85
86   thread.Start();
87   EXPECT_TRUE(thread.HasBeenStarted());
88   EXPECT_FALSE(thread.HasBeenJoined());
89
90   thread.Join();
91   EXPECT_TRUE(thread.HasBeenStarted());
92   EXPECT_TRUE(thread.HasBeenJoined());
93   EXPECT_EQ(7, stack_int);
94 }
95
96 TEST(SimpleThreadTest, WaitForEvent) {
97   // Create a thread, and wait for it to signal us.
98   WaitableEvent event(true, false);
99
100   WaitEventRunner runner(&event);
101   DelegateSimpleThread thread(&runner, "event_waiter");
102
103   EXPECT_FALSE(event.IsSignaled());
104   thread.Start();
105   event.Wait();
106   EXPECT_TRUE(event.IsSignaled());
107   thread.Join();
108 }
109
110 TEST(SimpleThreadTest, NamedWithOptions) {
111   WaitableEvent event(true, false);
112
113   WaitEventRunner runner(&event);
114   SimpleThread::Options options;
115   DelegateSimpleThread thread(&runner, "event_waiter", options);
116   EXPECT_EQ(thread.name_prefix(), "event_waiter");
117   EXPECT_FALSE(event.IsSignaled());
118
119   thread.Start();
120   EXPECT_EQ(thread.name_prefix(), "event_waiter");
121   EXPECT_EQ(thread.name(),
122             std::string("event_waiter/") + IntToString(thread.tid()));
123   event.Wait();
124
125   EXPECT_TRUE(event.IsSignaled());
126   thread.Join();
127
128   // We keep the name and tid, even after the thread is gone.
129   EXPECT_EQ(thread.name_prefix(), "event_waiter");
130   EXPECT_EQ(thread.name(),
131             std::string("event_waiter/") + IntToString(thread.tid()));
132 }
133
134 TEST(SimpleThreadTest, ThreadPool) {
135   AtomicSequenceNumber seq;
136   SeqRunner runner(&seq);
137   DelegateSimpleThreadPool pool("seq_runner", 10);
138
139   // Add work before we're running.
140   pool.AddWork(&runner, 300);
141
142   EXPECT_EQ(seq.GetNext(), 0);
143   pool.Start();
144
145   // Add work while we're running.
146   pool.AddWork(&runner, 300);
147
148   pool.JoinAll();
149
150   EXPECT_EQ(seq.GetNext(), 601);
151
152   // We can reuse our pool.  Verify that all 10 threads can actually run in
153   // parallel, so this test will only pass if there are actually 10 threads.
154   AtomicSequenceNumber seq2;
155   WaitableEvent event(true, false);
156   // Changing 9 to 10, for example, would cause us JoinAll() to never return.
157   VerifyPoolRunner verifier(&seq2, 9, &event);
158   pool.Start();
159
160   pool.AddWork(&verifier, 10);
161
162   pool.JoinAll();
163   EXPECT_EQ(seq2.GetNext(), 10);
164 }
165
166 }  // namespace base