1 // Copyright (c) 2006-2008 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/dynamic_annotations.h" 6 #include "base/lock.h" 7 #include "base/message_loop.h" 8 #include "base/string_util.h" 9 #include "base/thread.h" 10 #include "testing/gtest/include/gtest/gtest.h" 11 #include "testing/platform_test.h" 12 13 using base::Thread; 14 15 typedef PlatformTest ThreadTest; 16 17 namespace { 18 19 class ToggleValue : public Task { 20 public: 21 explicit ToggleValue(bool* value) : value_(value) { 22 ANNOTATE_BENIGN_RACE(value, "Test-only data race on boolean " 23 "in base/thread_unittest"); 24 } 25 virtual void Run() { 26 *value_ = !*value_; 27 } 28 private: 29 bool* value_; 30 }; 31 32 class SleepSome : public Task { 33 public: 34 explicit SleepSome(int msec) : msec_(msec) { 35 } 36 virtual void Run() { 37 PlatformThread::Sleep(msec_); 38 } 39 private: 40 int msec_; 41 }; 42 43 class SleepInsideInitThread : public Thread { 44 public: 45 SleepInsideInitThread() : Thread("none") { init_called_ = false; } 46 virtual ~SleepInsideInitThread() { } 47 48 virtual void Init() { 49 PlatformThread::Sleep(500); 50 init_called_ = true; 51 } 52 bool InitCalled() { return init_called_; } 53 private: 54 bool init_called_; 55 }; 56 57 } // namespace 58 59 TEST_F(ThreadTest, Restart) { 60 Thread a("Restart"); 61 a.Stop(); 62 EXPECT_FALSE(a.message_loop()); 63 EXPECT_FALSE(a.IsRunning()); 64 EXPECT_TRUE(a.Start()); 65 EXPECT_TRUE(a.message_loop()); 66 EXPECT_TRUE(a.IsRunning()); 67 a.Stop(); 68 EXPECT_FALSE(a.message_loop()); 69 EXPECT_FALSE(a.IsRunning()); 70 EXPECT_TRUE(a.Start()); 71 EXPECT_TRUE(a.message_loop()); 72 EXPECT_TRUE(a.IsRunning()); 73 a.Stop(); 74 EXPECT_FALSE(a.message_loop()); 75 EXPECT_FALSE(a.IsRunning()); 76 a.Stop(); 77 EXPECT_FALSE(a.message_loop()); 78 EXPECT_FALSE(a.IsRunning()); 79 } 80 81 TEST_F(ThreadTest, StartWithOptions_StackSize) { 82 Thread a("StartWithStackSize"); 83 // Ensure that the thread can work with only 12 kb and still process a 84 // message. 85 Thread::Options options; 86 options.stack_size = 12*1024; 87 EXPECT_TRUE(a.StartWithOptions(options)); 88 EXPECT_TRUE(a.message_loop()); 89 EXPECT_TRUE(a.IsRunning()); 90 91 bool was_invoked = false; 92 a.message_loop()->PostTask(FROM_HERE, new ToggleValue(&was_invoked)); 93 94 // wait for the task to run (we could use a kernel event here 95 // instead to avoid busy waiting, but this is sufficient for 96 // testing purposes). 97 for (int i = 100; i >= 0 && !was_invoked; --i) { 98 PlatformThread::Sleep(10); 99 } 100 EXPECT_TRUE(was_invoked); 101 } 102 103 TEST_F(ThreadTest, TwoTasks) { 104 bool was_invoked = false; 105 { 106 Thread a("TwoTasks"); 107 EXPECT_TRUE(a.Start()); 108 EXPECT_TRUE(a.message_loop()); 109 110 // Test that all events are dispatched before the Thread object is 111 // destroyed. We do this by dispatching a sleep event before the 112 // event that will toggle our sentinel value. 113 a.message_loop()->PostTask(FROM_HERE, new SleepSome(20)); 114 a.message_loop()->PostTask(FROM_HERE, new ToggleValue(&was_invoked)); 115 } 116 EXPECT_TRUE(was_invoked); 117 } 118 119 TEST_F(ThreadTest, StopSoon) { 120 Thread a("StopSoon"); 121 EXPECT_TRUE(a.Start()); 122 EXPECT_TRUE(a.message_loop()); 123 EXPECT_TRUE(a.IsRunning()); 124 a.StopSoon(); 125 a.StopSoon(); 126 a.Stop(); 127 EXPECT_FALSE(a.message_loop()); 128 EXPECT_FALSE(a.IsRunning()); 129 } 130 131 TEST_F(ThreadTest, ThreadName) { 132 Thread a("ThreadName"); 133 EXPECT_TRUE(a.Start()); 134 EXPECT_EQ("ThreadName", a.thread_name()); 135 } 136 137 // Make sure we can't use a thread between Start() and Init(). 138 TEST_F(ThreadTest, SleepInsideInit) { 139 SleepInsideInitThread t; 140 EXPECT_FALSE(t.InitCalled()); 141 t.Start(); 142 EXPECT_TRUE(t.InitCalled()); 143 } 144