| 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 <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| 11 #include "base/single_thread_task_runner.h" | 11 #include "base/single_thread_task_runner.h" |
| 12 #include "base/synchronization/waitable_event.h" |
| 12 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 13 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
| 13 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
| 14 #include "testing/platform_test.h" | 15 #include "testing/platform_test.h" |
| 15 | 16 |
| 16 using base::Thread; | 17 using base::Thread; |
| 17 | 18 |
| 18 typedef PlatformTest ThreadTest; | 19 typedef PlatformTest ThreadTest; |
| 19 | 20 |
| 20 namespace { | 21 namespace { |
| 21 | 22 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 private: | 99 private: |
| 99 EventList* event_list_; | 100 EventList* event_list_; |
| 100 }; | 101 }; |
| 101 | 102 |
| 102 // Task that adds a destruction observer to the current message loop. | 103 // Task that adds a destruction observer to the current message loop. |
| 103 void RegisterDestructionObserver( | 104 void RegisterDestructionObserver( |
| 104 base::MessageLoop::DestructionObserver* observer) { | 105 base::MessageLoop::DestructionObserver* observer) { |
| 105 base::MessageLoop::current()->AddDestructionObserver(observer); | 106 base::MessageLoop::current()->AddDestructionObserver(observer); |
| 106 } | 107 } |
| 107 | 108 |
| 109 // Task that calls GetThreadId() of |thread|, stores the result into |id|, then |
| 110 // signal |event|. |
| 111 void ReturnThreadId(base::Thread* thread, |
| 112 base::PlatformThreadId* id, |
| 113 base::WaitableEvent* event) { |
| 114 *id = thread->GetThreadId(); |
| 115 event->Signal(); |
| 116 } |
| 117 |
| 108 } // namespace | 118 } // namespace |
| 109 | 119 |
| 110 TEST_F(ThreadTest, Restart) { | 120 TEST_F(ThreadTest, Restart) { |
| 111 Thread a("Restart"); | 121 Thread a("Restart"); |
| 112 a.Stop(); | 122 a.Stop(); |
| 113 EXPECT_FALSE(a.message_loop()); | 123 EXPECT_FALSE(a.message_loop()); |
| 114 EXPECT_FALSE(a.IsRunning()); | 124 EXPECT_FALSE(a.IsRunning()); |
| 115 EXPECT_TRUE(a.Start()); | 125 EXPECT_TRUE(a.Start()); |
| 116 EXPECT_TRUE(a.message_loop()); | 126 EXPECT_TRUE(a.message_loop()); |
| 117 EXPECT_TRUE(a.IsRunning()); | 127 EXPECT_TRUE(a.IsRunning()); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 EXPECT_FALSE(a.message_loop()); | 197 EXPECT_FALSE(a.message_loop()); |
| 188 EXPECT_FALSE(a.IsRunning()); | 198 EXPECT_FALSE(a.IsRunning()); |
| 189 } | 199 } |
| 190 | 200 |
| 191 TEST_F(ThreadTest, ThreadName) { | 201 TEST_F(ThreadTest, ThreadName) { |
| 192 Thread a("ThreadName"); | 202 Thread a("ThreadName"); |
| 193 EXPECT_TRUE(a.Start()); | 203 EXPECT_TRUE(a.Start()); |
| 194 EXPECT_EQ("ThreadName", a.thread_name()); | 204 EXPECT_EQ("ThreadName", a.thread_name()); |
| 195 } | 205 } |
| 196 | 206 |
| 207 TEST_F(ThreadTest, ThreadId) { |
| 208 Thread a("ThreadId0"); |
| 209 Thread b("ThreadId1"); |
| 210 a.Start(); |
| 211 b.Start(); |
| 212 |
| 213 // Post a task that calls GetThreadId() on the created thread. |
| 214 base::WaitableEvent event(false, false); |
| 215 base::PlatformThreadId id_from_new_thread; |
| 216 a.task_runner()->PostTask( |
| 217 FROM_HERE, base::Bind(ReturnThreadId, &a, &id_from_new_thread, &event)); |
| 218 |
| 219 // Call GetThreadId() on the current thread before calling event.Wait() so |
| 220 // that this test can find a race issue with TSAN. |
| 221 base::PlatformThreadId id_from_current_thread = a.GetThreadId(); |
| 222 |
| 223 // Check if GetThreadId() returns consistent value in both threads. |
| 224 event.Wait(); |
| 225 EXPECT_EQ(id_from_current_thread, id_from_new_thread); |
| 226 |
| 227 // A started thread should have a valid ID. |
| 228 EXPECT_NE(base::kInvalidThreadId, a.GetThreadId()); |
| 229 EXPECT_NE(base::kInvalidThreadId, b.GetThreadId()); |
| 230 |
| 231 // Each thread should have a different thread ID. |
| 232 EXPECT_NE(a.GetThreadId(), b.GetThreadId()); |
| 233 } |
| 234 |
| 235 TEST_F(ThreadTest, ThreadIdWithRestart) { |
| 236 Thread a("ThreadIdWithRestart"); |
| 237 base::PlatformThreadId previous_id = base::kInvalidThreadId; |
| 238 |
| 239 for (size_t i = 0; i < 16; ++i) { |
| 240 EXPECT_TRUE(a.Start()); |
| 241 base::PlatformThreadId current_id = a.GetThreadId(); |
| 242 EXPECT_NE(previous_id, current_id); |
| 243 previous_id = current_id; |
| 244 a.Stop(); |
| 245 } |
| 246 } |
| 247 |
| 197 // Make sure Init() is called after Start() and before | 248 // Make sure Init() is called after Start() and before |
| 198 // WaitUntilThreadInitialized() returns. | 249 // WaitUntilThreadInitialized() returns. |
| 199 TEST_F(ThreadTest, SleepInsideInit) { | 250 TEST_F(ThreadTest, SleepInsideInit) { |
| 200 SleepInsideInitThread t; | 251 SleepInsideInitThread t; |
| 201 EXPECT_FALSE(t.InitCalled()); | 252 EXPECT_FALSE(t.InitCalled()); |
| 202 t.StartAndWaitForTesting(); | 253 t.StartAndWaitForTesting(); |
| 203 EXPECT_TRUE(t.InitCalled()); | 254 EXPECT_TRUE(t.InitCalled()); |
| 204 } | 255 } |
| 205 | 256 |
| 206 // Make sure that the destruction sequence is: | 257 // Make sure that the destruction sequence is: |
| (...skipping 25 matching lines...) Expand all Loading... |
| 232 ASSERT_EQ(static_cast<size_t>(THREAD_NUM_EVENTS), captured_events.size()); | 283 ASSERT_EQ(static_cast<size_t>(THREAD_NUM_EVENTS), captured_events.size()); |
| 233 EXPECT_EQ(THREAD_EVENT_INIT, captured_events[0]); | 284 EXPECT_EQ(THREAD_EVENT_INIT, captured_events[0]); |
| 234 EXPECT_EQ(THREAD_EVENT_CLEANUP, captured_events[1]); | 285 EXPECT_EQ(THREAD_EVENT_CLEANUP, captured_events[1]); |
| 235 EXPECT_EQ(THREAD_EVENT_MESSAGE_LOOP_DESTROYED, captured_events[2]); | 286 EXPECT_EQ(THREAD_EVENT_MESSAGE_LOOP_DESTROYED, captured_events[2]); |
| 236 } | 287 } |
| 237 | 288 |
| 238 TEST_F(ThreadTest, ThreadNotStarted) { | 289 TEST_F(ThreadTest, ThreadNotStarted) { |
| 239 Thread a("Inert"); | 290 Thread a("Inert"); |
| 240 EXPECT_EQ(nullptr, a.task_runner()); | 291 EXPECT_EQ(nullptr, a.task_runner()); |
| 241 } | 292 } |
| OLD | NEW |