| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 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 | 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/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 10 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 base::PlatformThread::Sleep(500); | 50 base::PlatformThread::Sleep(500); |
| 51 init_called_ = true; | 51 init_called_ = true; |
| 52 } | 52 } |
| 53 bool InitCalled() { return init_called_; } | 53 bool InitCalled() { return init_called_; } |
| 54 private: | 54 private: |
| 55 bool init_called_; | 55 bool init_called_; |
| 56 }; | 56 }; |
| 57 | 57 |
| 58 enum ThreadEvent { | 58 enum ThreadEvent { |
| 59 // Thread::Init() was called. | 59 // Thread::Init() was called. |
| 60 THREAD_EVENT_INIT, | 60 THREAD_EVENT_INIT = 0, |
| 61 | 61 |
| 62 // The MessageLoop for the thread was deleted. | 62 // The MessageLoop for the thread was deleted. |
| 63 THREAD_EVENT_MESSAGE_LOOP_DESTROYED, | 63 THREAD_EVENT_MESSAGE_LOOP_DESTROYED, |
| 64 | 64 |
| 65 // Thread::CleanUp() was called. | 65 // Thread::CleanUp() was called. |
| 66 THREAD_EVENT_CLEANUP, | 66 THREAD_EVENT_CLEANUP, |
| 67 | 67 |
| 68 // Thread::CleanUpAfterMessageLoopDestruction() was called. | 68 // Keep at end of list. |
| 69 THREAD_EVENT_CLEANUP_AFTER_LOOP, | 69 THREAD_NUM_EVENTS |
| 70 }; | 70 }; |
| 71 | 71 |
| 72 typedef std::vector<ThreadEvent> EventList; | 72 typedef std::vector<ThreadEvent> EventList; |
| 73 | 73 |
| 74 class CaptureToEventList : public Thread { | 74 class CaptureToEventList : public Thread { |
| 75 public: | 75 public: |
| 76 // This Thread pushes events into the vector |event_list| to show | 76 // This Thread pushes events into the vector |event_list| to show |
| 77 // the order they occured in. |event_list| must remain valid for the | 77 // the order they occured in. |event_list| must remain valid for the |
| 78 // lifetime of this thread. | 78 // lifetime of this thread. |
| 79 explicit CaptureToEventList(EventList* event_list) | 79 explicit CaptureToEventList(EventList* event_list) |
| 80 : Thread("none"), event_list_(event_list) { | 80 : Thread("none"), event_list_(event_list) { |
| 81 } | 81 } |
| 82 | 82 |
| 83 virtual ~CaptureToEventList() { | 83 virtual ~CaptureToEventList() { |
| 84 // Must call Stop() manually to have our CleanUp() function called. | 84 // Must call Stop() manually to have our CleanUp() function called. |
| 85 Stop(); | 85 Stop(); |
| 86 } | 86 } |
| 87 | 87 |
| 88 virtual void Init() { | 88 virtual void Init() { |
| 89 event_list_->push_back(THREAD_EVENT_INIT); | 89 event_list_->push_back(THREAD_EVENT_INIT); |
| 90 } | 90 } |
| 91 | 91 |
| 92 virtual void CleanUp() { | 92 virtual void CleanUp() { |
| 93 event_list_->push_back(THREAD_EVENT_CLEANUP); | 93 event_list_->push_back(THREAD_EVENT_CLEANUP); |
| 94 } | 94 } |
| 95 | 95 |
| 96 virtual void CleanUpAfterMessageLoopDestruction() { | |
| 97 event_list_->push_back(THREAD_EVENT_CLEANUP_AFTER_LOOP); | |
| 98 } | |
| 99 | |
| 100 private: | 96 private: |
| 101 EventList* event_list_; | 97 EventList* event_list_; |
| 102 }; | 98 }; |
| 103 | 99 |
| 104 // Observer that writes a value into |event_list| when a message loop has been | 100 // Observer that writes a value into |event_list| when a message loop has been |
| 105 // destroyed. | 101 // destroyed. |
| 106 class CapturingDestructionObserver : public MessageLoop::DestructionObserver { | 102 class CapturingDestructionObserver : public MessageLoop::DestructionObserver { |
| 107 public: | 103 public: |
| 108 // |event_list| must remain valid throughout the observer's lifetime. | 104 // |event_list| must remain valid throughout the observer's lifetime. |
| 109 explicit CapturingDestructionObserver(EventList* event_list) | 105 explicit CapturingDestructionObserver(EventList* event_list) |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 EXPECT_FALSE(t.InitCalled()); | 219 EXPECT_FALSE(t.InitCalled()); |
| 224 t.Start(); | 220 t.Start(); |
| 225 EXPECT_TRUE(t.InitCalled()); | 221 EXPECT_TRUE(t.InitCalled()); |
| 226 } | 222 } |
| 227 | 223 |
| 228 // Make sure that the destruction sequence is: | 224 // Make sure that the destruction sequence is: |
| 229 // | 225 // |
| 230 // (1) Thread::CleanUp() | 226 // (1) Thread::CleanUp() |
| 231 // (2) MessageLoop::~MessageLoop() | 227 // (2) MessageLoop::~MessageLoop() |
| 232 // MessageLoop::DestructionObservers called. | 228 // MessageLoop::DestructionObservers called. |
| 233 // (3) Thread::CleanUpAfterMessageLoopDestruction | |
| 234 TEST_F(ThreadTest, CleanUp) { | 229 TEST_F(ThreadTest, CleanUp) { |
| 235 EventList captured_events; | 230 EventList captured_events; |
| 236 CapturingDestructionObserver loop_destruction_observer(&captured_events); | 231 CapturingDestructionObserver loop_destruction_observer(&captured_events); |
| 237 | 232 |
| 238 { | 233 { |
| 239 // Start a thread which writes its event into |captured_events|. | 234 // Start a thread which writes its event into |captured_events|. |
| 240 CaptureToEventList t(&captured_events); | 235 CaptureToEventList t(&captured_events); |
| 241 EXPECT_TRUE(t.Start()); | 236 EXPECT_TRUE(t.Start()); |
| 242 EXPECT_TRUE(t.message_loop()); | 237 EXPECT_TRUE(t.message_loop()); |
| 243 EXPECT_TRUE(t.IsRunning()); | 238 EXPECT_TRUE(t.IsRunning()); |
| 244 | 239 |
| 245 // Register an observer that writes into |captured_events| once the | 240 // Register an observer that writes into |captured_events| once the |
| 246 // thread's message loop is destroyed. | 241 // thread's message loop is destroyed. |
| 247 t.message_loop()->PostTask( | 242 t.message_loop()->PostTask( |
| 248 FROM_HERE, | 243 FROM_HERE, |
| 249 new RegisterDestructionObserver(&loop_destruction_observer)); | 244 new RegisterDestructionObserver(&loop_destruction_observer)); |
| 250 | 245 |
| 251 // Upon leaving this scope, the thread is deleted. | 246 // Upon leaving this scope, the thread is deleted. |
| 252 } | 247 } |
| 253 | 248 |
| 254 // Check the order of events during shutdown. | 249 // Check the order of events during shutdown. |
| 255 ASSERT_EQ(4u, captured_events.size()); | 250 ASSERT_EQ(static_cast<size_t>(THREAD_NUM_EVENTS), captured_events.size()); |
| 256 EXPECT_EQ(THREAD_EVENT_INIT, captured_events[0]); | 251 EXPECT_EQ(THREAD_EVENT_INIT, captured_events[0]); |
| 257 EXPECT_EQ(THREAD_EVENT_CLEANUP, captured_events[1]); | 252 EXPECT_EQ(THREAD_EVENT_CLEANUP, captured_events[1]); |
| 258 EXPECT_EQ(THREAD_EVENT_MESSAGE_LOOP_DESTROYED, captured_events[2]); | 253 EXPECT_EQ(THREAD_EVENT_MESSAGE_LOOP_DESTROYED, captured_events[2]); |
| 259 EXPECT_EQ(THREAD_EVENT_CLEANUP_AFTER_LOOP, captured_events[3]); | |
| 260 } | 254 } |
| OLD | NEW |