OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/threading/thread.h" | 5 #include "base/threading/thread.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/location.h" | |
13 #include "base/single_thread_task_runner.h" | 12 #include "base/single_thread_task_runner.h" |
14 #include "base/synchronization/waitable_event.h" | 13 #include "base/synchronization/waitable_event.h" |
15 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 14 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
| 15 #include "base/threading/platform_thread.h" |
16 #include "build/build_config.h" | 16 #include "build/build_config.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
18 #include "testing/platform_test.h" | 18 #include "testing/platform_test.h" |
19 | 19 |
| 20 // Death tests misbehave on Android. |
| 21 // TODO(gab): Remove this when https://codereview.chromium.org/2162053006 |
| 22 // lands. |
| 23 #if DCHECK_IS_ON() && defined(GTEST_HAS_DEATH_TEST) && !defined(OS_ANDROID) |
| 24 #define EXPECT_DCHECK_DEATH(statement, regex) EXPECT_DEATH(statement, regex) |
| 25 #else |
| 26 #define EXPECT_DCHECK_DEATH(statement, regex) |
| 27 #endif |
| 28 |
20 using base::Thread; | 29 using base::Thread; |
21 | 30 |
22 typedef PlatformTest ThreadTest; | 31 typedef PlatformTest ThreadTest; |
23 | 32 |
24 namespace { | 33 namespace { |
25 | 34 |
26 void ToggleValue(bool* value) { | 35 void ToggleValue(bool* value) { |
27 ANNOTATE_BENIGN_RACE(value, "Test-only data race on boolean " | 36 ANNOTATE_BENIGN_RACE(value, "Test-only data race on boolean " |
28 "in base/thread_unittest"); | 37 "in base/thread_unittest"); |
29 *value = !*value; | 38 *value = !*value; |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 EXPECT_TRUE(a.message_loop()); | 166 EXPECT_TRUE(a.message_loop()); |
158 EXPECT_TRUE(a.IsRunning()); | 167 EXPECT_TRUE(a.IsRunning()); |
159 | 168 |
160 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, | 169 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
161 base::WaitableEvent::InitialState::NOT_SIGNALED); | 170 base::WaitableEvent::InitialState::NOT_SIGNALED); |
162 a.task_runner()->PostTask(FROM_HERE, base::Bind(&base::WaitableEvent::Signal, | 171 a.task_runner()->PostTask(FROM_HERE, base::Bind(&base::WaitableEvent::Signal, |
163 base::Unretained(&event))); | 172 base::Unretained(&event))); |
164 event.Wait(); | 173 event.Wait(); |
165 } | 174 } |
166 | 175 |
167 TEST_F(ThreadTest, TwoTasks) { | 176 TEST_F(ThreadTest, StartWithOptions_NonJoinable) { |
| 177 Thread a("StartNonJoinable"); |
| 178 Thread::Options options; |
| 179 options.joinable = false; |
| 180 EXPECT_TRUE(a.StartWithOptions(options)); |
| 181 EXPECT_TRUE(a.message_loop()); |
| 182 EXPECT_TRUE(a.IsRunning()); |
| 183 |
| 184 // Without this call this test is racy. The above IsRunning() succeeds because |
| 185 // of an early-return condition while between Start() and Stop(), after |
| 186 // invoking Stop() below this early-return condition is no longer satisfied |
| 187 // and the real |is_running_| bit has to be checked. It could still be false |
| 188 // if the message loop hasn't started for real in practice. This is only a |
| 189 // requirement for this test because the non-joinable thread makes it possible |
| 190 // to return from Stop() before the thread has even started. |
| 191 EXPECT_TRUE(a.WaitUntilThreadStarted()); |
| 192 |
| 193 // Make the thread block until |block_event| is signaled. |
| 194 base::WaitableEvent block_event( |
| 195 base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 196 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 197 a.task_runner()->PostTask( |
| 198 FROM_HERE, |
| 199 base::Bind(&base::WaitableEvent::Wait, base::Unretained(&block_event))); |
| 200 |
| 201 // Stop() shouldn't block despite the thread still being alive. |
| 202 a.Stop(); |
| 203 EXPECT_TRUE(a.IsRunning()); |
| 204 |
| 205 // Unblock the task and give a bit of extra time to unwind QuitWhenIdle(). |
| 206 block_event.Signal(); |
| 207 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20)); |
| 208 |
| 209 // The thread should now have stopped on its own. |
| 210 EXPECT_FALSE(a.IsRunning()); |
| 211 } |
| 212 |
| 213 TEST_F(ThreadTest, TwoTasksOnJoinableThread) { |
168 bool was_invoked = false; | 214 bool was_invoked = false; |
169 { | 215 { |
170 Thread a("TwoTasks"); | 216 Thread a("TwoTasksOnJoinableThread"); |
171 EXPECT_TRUE(a.Start()); | 217 EXPECT_TRUE(a.Start()); |
172 EXPECT_TRUE(a.message_loop()); | 218 EXPECT_TRUE(a.message_loop()); |
173 | 219 |
174 // Test that all events are dispatched before the Thread object is | 220 // Test that all events are dispatched before the Thread object is |
175 // destroyed. We do this by dispatching a sleep event before the | 221 // destroyed. We do this by dispatching a sleep event before the |
176 // event that will toggle our sentinel value. | 222 // event that will toggle our sentinel value. |
177 a.task_runner()->PostTask( | 223 a.task_runner()->PostTask( |
178 FROM_HERE, base::Bind(static_cast<void (*)(base::TimeDelta)>( | 224 FROM_HERE, base::Bind(static_cast<void (*)(base::TimeDelta)>( |
179 &base::PlatformThread::Sleep), | 225 &base::PlatformThread::Sleep), |
180 base::TimeDelta::FromMilliseconds(20))); | 226 base::TimeDelta::FromMilliseconds(20))); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 EXPECT_FALSE(a.IsRunning()); | 270 EXPECT_FALSE(a.IsRunning()); |
225 | 271 |
226 EXPECT_TRUE(a.Start()); | 272 EXPECT_TRUE(a.Start()); |
227 EXPECT_TRUE(a.message_loop()); | 273 EXPECT_TRUE(a.message_loop()); |
228 EXPECT_TRUE(a.IsRunning()); | 274 EXPECT_TRUE(a.IsRunning()); |
229 a.Stop(); | 275 a.Stop(); |
230 EXPECT_FALSE(a.message_loop()); | 276 EXPECT_FALSE(a.message_loop()); |
231 EXPECT_FALSE(a.IsRunning()); | 277 EXPECT_FALSE(a.IsRunning()); |
232 } | 278 } |
233 | 279 |
| 280 TEST_F(ThreadTest, StartTwiceNonJoinableNotAllowed) { |
| 281 Thread a("StartTwiceNonJoinable"); |
| 282 |
| 283 Thread::Options options; |
| 284 options.joinable = false; |
| 285 EXPECT_TRUE(a.StartWithOptions(options)); |
| 286 EXPECT_TRUE(a.message_loop()); |
| 287 EXPECT_TRUE(a.IsRunning()); |
| 288 |
| 289 // Signaled when last task on |a| is processed. |
| 290 base::WaitableEvent last_task_event( |
| 291 base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 292 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 293 a.task_runner()->PostTask( |
| 294 FROM_HERE, |
| 295 base::Bind(&base::WaitableEvent::Signal, |
| 296 base::Unretained(&last_task_event))); |
| 297 |
| 298 // Stop() is non-blocking, but Yield() to |a|, wait for last task to be |
| 299 // processed and a little more for QuitWhenIdle() to unwind before considering |
| 300 // the thread "stopped". |
| 301 a.Stop(); |
| 302 base::PlatformThread::YieldCurrentThread(); |
| 303 last_task_event.Wait(); |
| 304 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20)); |
| 305 |
| 306 // This test assumes that the above was sufficient to let the thread fully |
| 307 // stop. |
| 308 ASSERT_FALSE(a.IsRunning()); |
| 309 |
| 310 // Restarting it should not be allowed. |
| 311 EXPECT_DCHECK_DEATH(a.Start(), ""); |
| 312 } |
| 313 |
234 TEST_F(ThreadTest, ThreadName) { | 314 TEST_F(ThreadTest, ThreadName) { |
235 Thread a("ThreadName"); | 315 Thread a("ThreadName"); |
236 EXPECT_TRUE(a.Start()); | 316 EXPECT_TRUE(a.Start()); |
237 EXPECT_EQ("ThreadName", a.thread_name()); | 317 EXPECT_EQ("ThreadName", a.thread_name()); |
238 } | 318 } |
239 | 319 |
240 TEST_F(ThreadTest, ThreadId) { | 320 TEST_F(ThreadTest, ThreadId) { |
241 Thread a("ThreadId0"); | 321 Thread a("ThreadId0"); |
242 Thread b("ThreadId1"); | 322 Thread b("ThreadId1"); |
243 a.Start(); | 323 a.Start(); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 EXPECT_FALSE(a.task_runner()); | 405 EXPECT_FALSE(a.task_runner()); |
326 } | 406 } |
327 | 407 |
328 TEST_F(ThreadTest, MultipleWaitUntilThreadStarted) { | 408 TEST_F(ThreadTest, MultipleWaitUntilThreadStarted) { |
329 Thread a("MultipleWaitUntilThreadStarted"); | 409 Thread a("MultipleWaitUntilThreadStarted"); |
330 EXPECT_TRUE(a.Start()); | 410 EXPECT_TRUE(a.Start()); |
331 // It's OK to call WaitUntilThreadStarted() multiple times. | 411 // It's OK to call WaitUntilThreadStarted() multiple times. |
332 EXPECT_TRUE(a.WaitUntilThreadStarted()); | 412 EXPECT_TRUE(a.WaitUntilThreadStarted()); |
333 EXPECT_TRUE(a.WaitUntilThreadStarted()); | 413 EXPECT_TRUE(a.WaitUntilThreadStarted()); |
334 } | 414 } |
OLD | NEW |