OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 20 matching lines...) Expand all Loading... |
31 bool IsLocked_Worker() { | 31 bool IsLocked_Worker() { |
32 if (!crit_.TryEnter()) { | 32 if (!crit_.TryEnter()) { |
33 return true; | 33 return true; |
34 } | 34 } |
35 crit_.Leave(); | 35 crit_.Leave(); |
36 return false; | 36 return false; |
37 } | 37 } |
38 bool IsLocked() { | 38 bool IsLocked() { |
39 // We have to do this on a worker thread, or else the TryEnter will | 39 // We have to do this on a worker thread, or else the TryEnter will |
40 // succeed, since our critical sections are reentrant. | 40 // succeed, since our critical sections are reentrant. |
41 Thread worker; | 41 std::unique_ptr<Thread> worker(Thread::CreateWithSocketServer()); |
42 worker.Start(); | 42 worker->Start(); |
43 return worker.Invoke<bool>( | 43 return worker->Invoke<bool>( |
44 RTC_FROM_HERE, rtc::Bind(&MessageQueueTest::IsLocked_Worker, this)); | 44 RTC_FROM_HERE, rtc::Bind(&MessageQueueTest::IsLocked_Worker, this)); |
45 } | 45 } |
46 }; | 46 }; |
47 | 47 |
48 struct DeletedLockChecker { | 48 struct DeletedLockChecker { |
49 DeletedLockChecker(MessageQueueTest* test, bool* was_locked, bool* deleted) | 49 DeletedLockChecker(MessageQueueTest* test, bool* was_locked, bool* deleted) |
50 : test(test), was_locked(was_locked), deleted(deleted) { } | 50 : test(test), was_locked(was_locked), deleted(deleted) { } |
51 ~DeletedLockChecker() { | 51 ~DeletedLockChecker() { |
52 *deleted = true; | 52 *deleted = true; |
53 *was_locked = test->IsLocked(); | 53 *was_locked = test->IsLocked(); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 delete handler; | 145 delete handler; |
146 EXPECT_TRUE(deleted); | 146 EXPECT_TRUE(deleted); |
147 EXPECT_FALSE(MessageQueueManager::IsInitialized()); | 147 EXPECT_FALSE(MessageQueueManager::IsInitialized()); |
148 } | 148 } |
149 | 149 |
150 // Ensure that ProcessAllMessageQueues does its essential function; process | 150 // Ensure that ProcessAllMessageQueues does its essential function; process |
151 // all messages (both delayed and non delayed) up until the current time, on | 151 // all messages (both delayed and non delayed) up until the current time, on |
152 // all registered message queues. | 152 // all registered message queues. |
153 TEST(MessageQueueManager, ProcessAllMessageQueues) { | 153 TEST(MessageQueueManager, ProcessAllMessageQueues) { |
154 Event entered_process_all_message_queues(true, false); | 154 Event entered_process_all_message_queues(true, false); |
155 Thread a; | 155 auto a = Thread::CreateWithSocketServer(); |
156 Thread b; | 156 auto b = Thread::CreateWithSocketServer(); |
157 a.Start(); | 157 a->Start(); |
158 b.Start(); | 158 b->Start(); |
159 | 159 |
160 volatile int messages_processed = 0; | 160 volatile int messages_processed = 0; |
161 FunctorMessageHandler<void, std::function<void()>> incrementer( | 161 FunctorMessageHandler<void, std::function<void()>> incrementer( |
162 [&messages_processed, &entered_process_all_message_queues] { | 162 [&messages_processed, &entered_process_all_message_queues] { |
163 // Wait for event as a means to ensure Increment doesn't occur outside | 163 // Wait for event as a means to ensure Increment doesn't occur outside |
164 // of ProcessAllMessageQueues. The event is set by a message posted to | 164 // of ProcessAllMessageQueues. The event is set by a message posted to |
165 // the main thread, which is guaranteed to be handled inside | 165 // the main thread, which is guaranteed to be handled inside |
166 // ProcessAllMessageQueues. | 166 // ProcessAllMessageQueues. |
167 entered_process_all_message_queues.Wait(Event::kForever); | 167 entered_process_all_message_queues.Wait(Event::kForever); |
168 AtomicOps::Increment(&messages_processed); | 168 AtomicOps::Increment(&messages_processed); |
169 }); | 169 }); |
170 FunctorMessageHandler<void, std::function<void()>> event_signaler( | 170 FunctorMessageHandler<void, std::function<void()>> event_signaler( |
171 [&entered_process_all_message_queues] { | 171 [&entered_process_all_message_queues] { |
172 entered_process_all_message_queues.Set(); | 172 entered_process_all_message_queues.Set(); |
173 }); | 173 }); |
174 | 174 |
175 // Post messages (both delayed and non delayed) to both threads. | 175 // Post messages (both delayed and non delayed) to both threads. |
176 a.Post(RTC_FROM_HERE, &incrementer); | 176 a->Post(RTC_FROM_HERE, &incrementer); |
177 b.Post(RTC_FROM_HERE, &incrementer); | 177 b->Post(RTC_FROM_HERE, &incrementer); |
178 a.PostDelayed(RTC_FROM_HERE, 0, &incrementer); | 178 a->PostDelayed(RTC_FROM_HERE, 0, &incrementer); |
179 b.PostDelayed(RTC_FROM_HERE, 0, &incrementer); | 179 b->PostDelayed(RTC_FROM_HERE, 0, &incrementer); |
180 rtc::Thread::Current()->Post(RTC_FROM_HERE, &event_signaler); | 180 rtc::Thread::Current()->Post(RTC_FROM_HERE, &event_signaler); |
181 | 181 |
182 MessageQueueManager::ProcessAllMessageQueues(); | 182 MessageQueueManager::ProcessAllMessageQueues(); |
183 EXPECT_EQ(4, AtomicOps::AcquireLoad(&messages_processed)); | 183 EXPECT_EQ(4, AtomicOps::AcquireLoad(&messages_processed)); |
184 } | 184 } |
185 | 185 |
186 // Test that ProcessAllMessageQueues doesn't hang if a thread is quitting. | 186 // Test that ProcessAllMessageQueues doesn't hang if a thread is quitting. |
187 TEST(MessageQueueManager, ProcessAllMessageQueuesWithQuittingThread) { | 187 TEST(MessageQueueManager, ProcessAllMessageQueuesWithQuittingThread) { |
188 Thread t; | 188 auto t = Thread::CreateWithSocketServer(); |
189 t.Start(); | 189 t->Start(); |
190 t.Quit(); | 190 t->Quit(); |
191 MessageQueueManager::ProcessAllMessageQueues(); | 191 MessageQueueManager::ProcessAllMessageQueues(); |
192 } | 192 } |
193 | 193 |
194 // Test that ProcessAllMessageQueues doesn't hang if a queue clears its | 194 // Test that ProcessAllMessageQueues doesn't hang if a queue clears its |
195 // messages. | 195 // messages. |
196 TEST(MessageQueueManager, ProcessAllMessageQueuesWithClearedQueue) { | 196 TEST(MessageQueueManager, ProcessAllMessageQueuesWithClearedQueue) { |
197 Event entered_process_all_message_queues(true, false); | 197 Event entered_process_all_message_queues(true, false); |
198 Thread t; | 198 auto t = Thread::CreateWithSocketServer(); |
199 t.Start(); | 199 t->Start(); |
200 | 200 |
201 FunctorMessageHandler<void, std::function<void()>> clearer( | 201 FunctorMessageHandler<void, std::function<void()>> clearer( |
202 [&entered_process_all_message_queues] { | 202 [&entered_process_all_message_queues] { |
203 // Wait for event as a means to ensure Clear doesn't occur outside of | 203 // Wait for event as a means to ensure Clear doesn't occur outside of |
204 // ProcessAllMessageQueues. The event is set by a message posted to the | 204 // ProcessAllMessageQueues. The event is set by a message posted to the |
205 // main thread, which is guaranteed to be handled inside | 205 // main thread, which is guaranteed to be handled inside |
206 // ProcessAllMessageQueues. | 206 // ProcessAllMessageQueues. |
207 entered_process_all_message_queues.Wait(Event::kForever); | 207 entered_process_all_message_queues.Wait(Event::kForever); |
208 rtc::Thread::Current()->Clear(nullptr); | 208 rtc::Thread::Current()->Clear(nullptr); |
209 }); | 209 }); |
210 FunctorMessageHandler<void, std::function<void()>> event_signaler( | 210 FunctorMessageHandler<void, std::function<void()>> event_signaler( |
211 [&entered_process_all_message_queues] { | 211 [&entered_process_all_message_queues] { |
212 entered_process_all_message_queues.Set(); | 212 entered_process_all_message_queues.Set(); |
213 }); | 213 }); |
214 | 214 |
215 // Post messages (both delayed and non delayed) to both threads. | 215 // Post messages (both delayed and non delayed) to both threads. |
216 t.Post(RTC_FROM_HERE, &clearer); | 216 t->Post(RTC_FROM_HERE, &clearer); |
217 rtc::Thread::Current()->Post(RTC_FROM_HERE, &event_signaler); | 217 rtc::Thread::Current()->Post(RTC_FROM_HERE, &event_signaler); |
218 MessageQueueManager::ProcessAllMessageQueues(); | 218 MessageQueueManager::ProcessAllMessageQueues(); |
219 } | 219 } |
220 | 220 |
221 class RefCountedHandler | 221 class RefCountedHandler |
222 : public MessageHandler, | 222 : public MessageHandler, |
223 public rtc::RefCountInterface { | 223 public rtc::RefCountInterface { |
224 public: | 224 public: |
225 void OnMessage(Message* msg) override {} | 225 void OnMessage(Message* msg) override {} |
226 }; | 226 }; |
227 | 227 |
228 class EmptyHandler : public MessageHandler { | 228 class EmptyHandler : public MessageHandler { |
229 public: | 229 public: |
230 void OnMessage(Message* msg) override {} | 230 void OnMessage(Message* msg) override {} |
231 }; | 231 }; |
232 | 232 |
233 TEST(MessageQueueManager, ClearReentrant) { | 233 TEST(MessageQueueManager, ClearReentrant) { |
234 Thread t; | 234 std::unique_ptr<Thread> t(Thread::Create()); |
235 EmptyHandler handler; | 235 EmptyHandler handler; |
236 RefCountedHandler* inner_handler( | 236 RefCountedHandler* inner_handler( |
237 new rtc::RefCountedObject<RefCountedHandler>()); | 237 new rtc::RefCountedObject<RefCountedHandler>()); |
238 // When the empty handler is destroyed, it will clear messages queued for | 238 // When the empty handler is destroyed, it will clear messages queued for |
239 // itself. The message to be cleared itself wraps a MessageHandler object | 239 // itself. The message to be cleared itself wraps a MessageHandler object |
240 // (RefCountedHandler) so this will cause the message queue to be cleared | 240 // (RefCountedHandler) so this will cause the message queue to be cleared |
241 // again in a re-entrant fashion, which previously triggered a DCHECK. | 241 // again in a re-entrant fashion, which previously triggered a DCHECK. |
242 // The inner handler will be removed in a re-entrant fashion from the | 242 // The inner handler will be removed in a re-entrant fashion from the |
243 // message queue of the thread while the outer handler is removed, verifying | 243 // message queue of the thread while the outer handler is removed, verifying |
244 // that the iterator is not invalidated in "MessageQueue::Clear". | 244 // that the iterator is not invalidated in "MessageQueue::Clear". |
245 t.Post(RTC_FROM_HERE, inner_handler, 0); | 245 t->Post(RTC_FROM_HERE, inner_handler, 0); |
246 t.Post(RTC_FROM_HERE, &handler, 0, | 246 t->Post(RTC_FROM_HERE, &handler, 0, |
247 new ScopedRefMessageData<RefCountedHandler>(inner_handler)); | 247 new ScopedRefMessageData<RefCountedHandler>(inner_handler)); |
248 } | 248 } |
OLD | NEW |