1 /* 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "webrtc/base/messagequeue.h" 12 13 #include "webrtc/base/bind.h" 14 #include "webrtc/base/gunit.h" 15 #include "webrtc/base/logging.h" 16 #include "webrtc/base/thread.h" 17 #include "webrtc/base/timeutils.h" 18 #include "webrtc/base/nullsocketserver.h" 19 #include "webrtc/test/testsupport/gtest_disable.h" 20 21 using namespace rtc; 22 23 class MessageQueueTest: public testing::Test, public MessageQueue { 24 public: 25 bool IsLocked_Worker() { 26 if (!crit_.TryEnter()) { 27 return true; 28 } 29 crit_.Leave(); 30 return false; 31 } 32 bool IsLocked() { 33 // We have to do this on a worker thread, or else the TryEnter will 34 // succeed, since our critical sections are reentrant. 35 Thread worker; 36 worker.Start(); 37 return worker.Invoke<bool>( 38 rtc::Bind(&MessageQueueTest::IsLocked_Worker, this)); 39 } 40 }; 41 42 struct DeletedLockChecker { 43 DeletedLockChecker(MessageQueueTest* test, bool* was_locked, bool* deleted) 44 : test(test), was_locked(was_locked), deleted(deleted) { } 45 ~DeletedLockChecker() { 46 *deleted = true; 47 *was_locked = test->IsLocked(); 48 } 49 MessageQueueTest* test; 50 bool* was_locked; 51 bool* deleted; 52 }; 53 54 static void DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder( 55 MessageQueue* q) { 56 EXPECT_TRUE(q != NULL); 57 TimeStamp now = Time(); 58 q->PostAt(now, NULL, 3); 59 q->PostAt(now - 2, NULL, 0); 60 q->PostAt(now - 1, NULL, 1); 61 q->PostAt(now, NULL, 4); 62 q->PostAt(now - 1, NULL, 2); 63 64 Message msg; 65 for (size_t i=0; i<5; ++i) { 66 memset(&msg, 0, sizeof(msg)); 67 EXPECT_TRUE(q->Get(&msg, 0)); 68 EXPECT_EQ(i, msg.message_id); 69 } 70 71 EXPECT_FALSE(q->Get(&msg, 0)); // No more messages 72 } 73 74 TEST_F(MessageQueueTest, 75 DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder) { 76 MessageQueue q; 77 DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder(&q); 78 NullSocketServer nullss; 79 MessageQueue q_nullss(&nullss); 80 DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder(&q_nullss); 81 } 82 83 TEST_F(MessageQueueTest, DISABLED_ON_MAC(DisposeNotLocked)) { 84 bool was_locked = true; 85 bool deleted = false; 86 DeletedLockChecker* d = new DeletedLockChecker(this, &was_locked, &deleted); 87 Dispose(d); 88 Message msg; 89 EXPECT_FALSE(Get(&msg, 0)); 90 EXPECT_TRUE(deleted); 91 EXPECT_FALSE(was_locked); 92 } 93 94 class DeletedMessageHandler : public MessageHandler { 95 public: 96 explicit DeletedMessageHandler(bool* deleted) : deleted_(deleted) { } 97 ~DeletedMessageHandler() { 98 *deleted_ = true; 99 } 100 void OnMessage(Message* msg) { } 101 private: 102 bool* deleted_; 103 }; 104 105 TEST_F(MessageQueueTest, DiposeHandlerWithPostedMessagePending) { 106 bool deleted = false; 107 DeletedMessageHandler *handler = new DeletedMessageHandler(&deleted); 108 // First, post a dispose. 109 Dispose(handler); 110 // Now, post a message, which should *not* be returned by Get(). 111 Post(handler, 1); 112 Message msg; 113 EXPECT_FALSE(Get(&msg, 0)); 114 EXPECT_TRUE(deleted); 115 } 116 117 struct UnwrapMainThreadScope { 118 UnwrapMainThreadScope() : rewrap_(Thread::Current() != NULL) { 119 if (rewrap_) ThreadManager::Instance()->UnwrapCurrentThread(); 120 } 121 ~UnwrapMainThreadScope() { 122 if (rewrap_) ThreadManager::Instance()->WrapCurrentThread(); 123 } 124 private: 125 bool rewrap_; 126 }; 127 128 TEST(MessageQueueManager, Clear) { 129 UnwrapMainThreadScope s; 130 if (MessageQueueManager::IsInitialized()) { 131 LOG(LS_INFO) << "Unable to run MessageQueueManager::Clear test, since the " 132 << "MessageQueueManager was already initialized by some " 133 << "other test in this run."; 134 return; 135 } 136 bool deleted = false; 137 DeletedMessageHandler* handler = new DeletedMessageHandler(&deleted); 138 delete handler; 139 EXPECT_TRUE(deleted); 140 EXPECT_FALSE(MessageQueueManager::IsInitialized()); 141 } 142