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 |