• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
20 using namespace rtc;
21 
22 class MessageQueueTest: public testing::Test, public MessageQueue {
23  public:
IsLocked_Worker()24   bool IsLocked_Worker() {
25     if (!crit_.TryEnter()) {
26       return true;
27     }
28     crit_.Leave();
29     return false;
30   }
IsLocked()31   bool IsLocked() {
32     // We have to do this on a worker thread, or else the TryEnter will
33     // succeed, since our critical sections are reentrant.
34     Thread worker;
35     worker.Start();
36     return worker.Invoke<bool>(
37         rtc::Bind(&MessageQueueTest::IsLocked_Worker, this));
38   }
39 };
40 
41 struct DeletedLockChecker {
DeletedLockCheckerDeletedLockChecker42   DeletedLockChecker(MessageQueueTest* test, bool* was_locked, bool* deleted)
43       : test(test), was_locked(was_locked), deleted(deleted) { }
~DeletedLockCheckerDeletedLockChecker44   ~DeletedLockChecker() {
45     *deleted = true;
46     *was_locked = test->IsLocked();
47   }
48   MessageQueueTest* test;
49   bool* was_locked;
50   bool* deleted;
51 };
52 
DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder(MessageQueue * q)53 static void DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder(
54     MessageQueue* q) {
55   EXPECT_TRUE(q != NULL);
56   TimeStamp now = Time();
57   q->PostAt(now, NULL, 3);
58   q->PostAt(now - 2, NULL, 0);
59   q->PostAt(now - 1, NULL, 1);
60   q->PostAt(now, NULL, 4);
61   q->PostAt(now - 1, NULL, 2);
62 
63   Message msg;
64   for (size_t i=0; i<5; ++i) {
65     memset(&msg, 0, sizeof(msg));
66     EXPECT_TRUE(q->Get(&msg, 0));
67     EXPECT_EQ(i, msg.message_id);
68   }
69 
70   EXPECT_FALSE(q->Get(&msg, 0));  // No more messages
71 }
72 
TEST_F(MessageQueueTest,DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder)73 TEST_F(MessageQueueTest,
74        DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder) {
75   MessageQueue q;
76   DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder(&q);
77   NullSocketServer nullss;
78   MessageQueue q_nullss(&nullss);
79   DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder(&q_nullss);
80 }
81 
TEST_F(MessageQueueTest,DisposeNotLocked)82 TEST_F(MessageQueueTest, DisposeNotLocked) {
83   bool was_locked = true;
84   bool deleted = false;
85   DeletedLockChecker* d = new DeletedLockChecker(this, &was_locked, &deleted);
86   Dispose(d);
87   Message msg;
88   EXPECT_FALSE(Get(&msg, 0));
89   EXPECT_TRUE(deleted);
90   EXPECT_FALSE(was_locked);
91 }
92 
93 class DeletedMessageHandler : public MessageHandler {
94  public:
DeletedMessageHandler(bool * deleted)95   explicit DeletedMessageHandler(bool* deleted) : deleted_(deleted) { }
~DeletedMessageHandler()96   ~DeletedMessageHandler() {
97     *deleted_ = true;
98   }
OnMessage(Message * msg)99   void OnMessage(Message* msg) { }
100  private:
101   bool* deleted_;
102 };
103 
TEST_F(MessageQueueTest,DiposeHandlerWithPostedMessagePending)104 TEST_F(MessageQueueTest, DiposeHandlerWithPostedMessagePending) {
105   bool deleted = false;
106   DeletedMessageHandler *handler = new DeletedMessageHandler(&deleted);
107   // First, post a dispose.
108   Dispose(handler);
109   // Now, post a message, which should *not* be returned by Get().
110   Post(handler, 1);
111   Message msg;
112   EXPECT_FALSE(Get(&msg, 0));
113   EXPECT_TRUE(deleted);
114 }
115 
116 struct UnwrapMainThreadScope {
UnwrapMainThreadScopeUnwrapMainThreadScope117   UnwrapMainThreadScope() : rewrap_(Thread::Current() != NULL) {
118     if (rewrap_) ThreadManager::Instance()->UnwrapCurrentThread();
119   }
~UnwrapMainThreadScopeUnwrapMainThreadScope120   ~UnwrapMainThreadScope() {
121     if (rewrap_) ThreadManager::Instance()->WrapCurrentThread();
122   }
123  private:
124   bool rewrap_;
125 };
126 
TEST(MessageQueueManager,Clear)127 TEST(MessageQueueManager, Clear) {
128   UnwrapMainThreadScope s;
129   if (MessageQueueManager::IsInitialized()) {
130     LOG(LS_INFO) << "Unable to run MessageQueueManager::Clear test, since the "
131                  << "MessageQueueManager was already initialized by some "
132                  << "other test in this run.";
133     return;
134   }
135   bool deleted = false;
136   DeletedMessageHandler* handler = new DeletedMessageHandler(&deleted);
137   delete handler;
138   EXPECT_TRUE(deleted);
139   EXPECT_FALSE(MessageQueueManager::IsInitialized());
140 }
141