1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 53f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_loop.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/third_party/dynamic_annotations/dynamic_annotations.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/platform_test.h" 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottusing base::Thread; 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttypedef PlatformTest ThreadTest; 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace { 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ToggleValue : public Task { 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit ToggleValue(bool* value) : value_(value) { 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ANNOTATE_BENIGN_RACE(value, "Test-only data race on boolean " 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "in base/thread_unittest"); 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void Run() { 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *value_ = !*value_; 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool* value_; 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass SleepSome : public Task { 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit SleepSome(int msec) : msec_(msec) { 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void Run() { 383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::PlatformThread::Sleep(msec_); 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int msec_; 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass SleepInsideInitThread : public Thread { 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SleepInsideInitThread() : Thread("none") { init_called_ = false; } 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual ~SleepInsideInitThread() { } 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void Init() { 503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::PlatformThread::Sleep(500); 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott init_called_ = true; 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool InitCalled() { return init_called_; } 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool init_called_; 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum ThreadEvent { 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Thread::Init() was called. 60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen THREAD_EVENT_INIT = 0, 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The MessageLoop for the thread was deleted. 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch THREAD_EVENT_MESSAGE_LOOP_DESTROYED, 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Thread::CleanUp() was called. 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch THREAD_EVENT_CLEANUP, 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Keep at end of list. 69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen THREAD_NUM_EVENTS 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef std::vector<ThreadEvent> EventList; 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass CaptureToEventList : public Thread { 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This Thread pushes events into the vector |event_list| to show 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the order they occured in. |event_list| must remain valid for the 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // lifetime of this thread. 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit CaptureToEventList(EventList* event_list) 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : Thread("none"), event_list_(event_list) { 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~CaptureToEventList() { 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Must call Stop() manually to have our CleanUp() function called. 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Stop(); 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void Init() { 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch event_list_->push_back(THREAD_EVENT_INIT); 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void CleanUp() { 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch event_list_->push_back(THREAD_EVENT_CLEANUP); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EventList* event_list_; 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Observer that writes a value into |event_list| when a message loop has been 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// destroyed. 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass CapturingDestructionObserver : public MessageLoop::DestructionObserver { 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |event_list| must remain valid throughout the observer's lifetime. 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit CapturingDestructionObserver(EventList* event_list) 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : event_list_(event_list) { 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // DestructionObserver implementation: 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void WillDestroyCurrentMessageLoop() { 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch event_list_->push_back(THREAD_EVENT_MESSAGE_LOOP_DESTROYED); 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch event_list_ = NULL; 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EventList* event_list_; 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Task that adds a destruction observer to the current message loop. 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass RegisterDestructionObserver : public Task { 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit RegisterDestructionObserver( 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::DestructionObserver* observer) 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : observer_(observer) { 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void Run() { 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->AddDestructionObserver(observer_); 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_ = NULL; 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::DestructionObserver* observer_; 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ThreadTest, Restart) { 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Thread a("Restart"); 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott a.Stop(); 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(a.message_loop()); 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(a.IsRunning()); 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(a.Start()); 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(a.message_loop()); 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(a.IsRunning()); 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott a.Stop(); 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(a.message_loop()); 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(a.IsRunning()); 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(a.Start()); 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(a.message_loop()); 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(a.IsRunning()); 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott a.Stop(); 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(a.message_loop()); 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(a.IsRunning()); 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott a.Stop(); 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(a.message_loop()); 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(a.IsRunning()); 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ThreadTest, StartWithOptions_StackSize) { 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Thread a("StartWithStackSize"); 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Ensure that the thread can work with only 12 kb and still process a 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // message. 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Thread::Options options; 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott options.stack_size = 12*1024; 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(a.StartWithOptions(options)); 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(a.message_loop()); 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(a.IsRunning()); 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool was_invoked = false; 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott a.message_loop()->PostTask(FROM_HERE, new ToggleValue(&was_invoked)); 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // wait for the task to run (we could use a kernel event here 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // instead to avoid busy waiting, but this is sufficient for 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // testing purposes). 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 100; i >= 0 && !was_invoked; --i) { 1773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::PlatformThread::Sleep(10); 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(was_invoked); 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ThreadTest, TwoTasks) { 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool was_invoked = false; 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Thread a("TwoTasks"); 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(a.Start()); 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(a.message_loop()); 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Test that all events are dispatched before the Thread object is 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // destroyed. We do this by dispatching a sleep event before the 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // event that will toggle our sentinel value. 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott a.message_loop()->PostTask(FROM_HERE, new SleepSome(20)); 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott a.message_loop()->PostTask(FROM_HERE, new ToggleValue(&was_invoked)); 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(was_invoked); 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ThreadTest, StopSoon) { 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Thread a("StopSoon"); 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(a.Start()); 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(a.message_loop()); 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(a.IsRunning()); 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott a.StopSoon(); 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott a.StopSoon(); 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott a.Stop(); 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(a.message_loop()); 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(a.IsRunning()); 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ThreadTest, ThreadName) { 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Thread a("ThreadName"); 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(a.Start()); 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ("ThreadName", a.thread_name()); 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Make sure we can't use a thread between Start() and Init(). 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ThreadTest, SleepInsideInit) { 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SleepInsideInitThread t; 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(t.InitCalled()); 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott t.Start(); 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(t.InitCalled()); 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Make sure that the destruction sequence is: 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// (1) Thread::CleanUp() 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// (2) MessageLoop::~MessageLoop() 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// MessageLoop::DestructionObservers called. 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ThreadTest, CleanUp) { 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EventList captured_events; 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CapturingDestructionObserver loop_destruction_observer(&captured_events); 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Start a thread which writes its event into |captured_events|. 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CaptureToEventList t(&captured_events); 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(t.Start()); 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(t.message_loop()); 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(t.IsRunning()); 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Register an observer that writes into |captured_events| once the 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // thread's message loop is destroyed. 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch t.message_loop()->PostTask( 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FROM_HERE, 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new RegisterDestructionObserver(&loop_destruction_observer)); 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Upon leaving this scope, the thread is deleted. 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check the order of events during shutdown. 250dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASSERT_EQ(static_cast<size_t>(THREAD_NUM_EVENTS), captured_events.size()); 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(THREAD_EVENT_INIT, captured_events[0]); 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(THREAD_EVENT_CLEANUP, captured_events[1]); 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(THREAD_EVENT_MESSAGE_LOOP_DESTROYED, captured_events[2]); 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 255