blob: fc3a8f781d2b581638ff81d562279eddd7877408 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:261/*
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
20using namespace rtc;
21
decurtis@webrtc.org2af30572015-02-21 01:59:5022class MessageQueueTest: public testing::Test, public MessageQueue {
henrike@webrtc.orgf0488722014-05-13 18:00:2623 public:
danilchapbebf54c2016-04-28 08:32:4824 MessageQueueTest() : MessageQueue(SocketServer::CreateDefault(), true) {}
henrike@webrtc.orgf0488722014-05-13 18:00:2625 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>(
Taylor Brandstetter5d97a9a2016-06-10 21:17:2738 RTC_FROM_HERE, rtc::Bind(&MessageQueueTest::IsLocked_Worker, this));
decurtis@webrtc.org2bffc3c2015-02-21 01:45:0439 }
decurtis@webrtc.org2bffc3c2015-02-21 01:45:0440};
41
henrike@webrtc.orgf0488722014-05-13 18:00:2642struct DeletedLockChecker {
decurtis@webrtc.org2af30572015-02-21 01:59:5043 DeletedLockChecker(MessageQueueTest* test, bool* was_locked, bool* deleted)
44 : test(test), was_locked(was_locked), deleted(deleted) { }
henrike@webrtc.orgf0488722014-05-13 18:00:2645 ~DeletedLockChecker() {
46 *deleted = true;
decurtis@webrtc.org2af30572015-02-21 01:59:5047 *was_locked = test->IsLocked();
henrike@webrtc.orgf0488722014-05-13 18:00:2648 }
decurtis@webrtc.org2af30572015-02-21 01:59:5049 MessageQueueTest* test;
henrike@webrtc.orgf0488722014-05-13 18:00:2650 bool* was_locked;
51 bool* deleted;
52};
53
54static void DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder(
55 MessageQueue* q) {
56 EXPECT_TRUE(q != NULL);
Honghai Zhang82d78622016-05-06 18:29:1557 int64_t now = TimeMillis();
Taylor Brandstetter5d97a9a2016-06-10 21:17:2758 q->PostAt(RTC_FROM_HERE, now, NULL, 3);
59 q->PostAt(RTC_FROM_HERE, now - 2, NULL, 0);
60 q->PostAt(RTC_FROM_HERE, now - 1, NULL, 1);
61 q->PostAt(RTC_FROM_HERE, now, NULL, 4);
62 q->PostAt(RTC_FROM_HERE, now - 1, NULL, 2);
henrike@webrtc.orgf0488722014-05-13 18:00:2663
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
74TEST_F(MessageQueueTest,
75 DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder) {
danilchapbebf54c2016-04-28 08:32:4876 MessageQueue q(SocketServer::CreateDefault(), true);
decurtis@webrtc.org2af30572015-02-21 01:59:5077 DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder(&q);
danilchapbebf54c2016-04-28 08:32:4878
henrike@webrtc.orgf0488722014-05-13 18:00:2679 NullSocketServer nullss;
danilchapbebf54c2016-04-28 08:32:4880 MessageQueue q_nullss(&nullss, true);
henrike@webrtc.orgf0488722014-05-13 18:00:2681 DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder(&q_nullss);
82}
83
henrike@webrtc.orgc732a3e2014-10-09 22:08:1584TEST_F(MessageQueueTest, DisposeNotLocked) {
henrike@webrtc.orgf0488722014-05-13 18:00:2685 bool was_locked = true;
86 bool deleted = false;
decurtis@webrtc.org2af30572015-02-21 01:59:5087 DeletedLockChecker* d = new DeletedLockChecker(this, &was_locked, &deleted);
88 Dispose(d);
henrike@webrtc.orgf0488722014-05-13 18:00:2689 Message msg;
decurtis@webrtc.org2af30572015-02-21 01:59:5090 EXPECT_FALSE(Get(&msg, 0));
henrike@webrtc.orgf0488722014-05-13 18:00:2691 EXPECT_TRUE(deleted);
92 EXPECT_FALSE(was_locked);
93}
94
95class DeletedMessageHandler : public MessageHandler {
96 public:
97 explicit DeletedMessageHandler(bool* deleted) : deleted_(deleted) { }
98 ~DeletedMessageHandler() {
99 *deleted_ = true;
100 }
101 void OnMessage(Message* msg) { }
102 private:
103 bool* deleted_;
104};
105
decurtis@webrtc.org2af30572015-02-21 01:59:50106TEST_F(MessageQueueTest, DiposeHandlerWithPostedMessagePending) {
henrike@webrtc.orgf0488722014-05-13 18:00:26107 bool deleted = false;
108 DeletedMessageHandler *handler = new DeletedMessageHandler(&deleted);
109 // First, post a dispose.
decurtis@webrtc.org2af30572015-02-21 01:59:50110 Dispose(handler);
henrike@webrtc.orgf0488722014-05-13 18:00:26111 // Now, post a message, which should *not* be returned by Get().
Taylor Brandstetter5d97a9a2016-06-10 21:17:27112 Post(RTC_FROM_HERE, handler, 1);
henrike@webrtc.orgf0488722014-05-13 18:00:26113 Message msg;
decurtis@webrtc.org2af30572015-02-21 01:59:50114 EXPECT_FALSE(Get(&msg, 0));
henrike@webrtc.orgf0488722014-05-13 18:00:26115 EXPECT_TRUE(deleted);
116}
117
118struct UnwrapMainThreadScope {
119 UnwrapMainThreadScope() : rewrap_(Thread::Current() != NULL) {
120 if (rewrap_) ThreadManager::Instance()->UnwrapCurrentThread();
121 }
122 ~UnwrapMainThreadScope() {
123 if (rewrap_) ThreadManager::Instance()->WrapCurrentThread();
124 }
125 private:
126 bool rewrap_;
127};
128
decurtis@webrtc.org2af30572015-02-21 01:59:50129TEST(MessageQueueManager, Clear) {
henrike@webrtc.orgf0488722014-05-13 18:00:26130 UnwrapMainThreadScope s;
131 if (MessageQueueManager::IsInitialized()) {
132 LOG(LS_INFO) << "Unable to run MessageQueueManager::Clear test, since the "
133 << "MessageQueueManager was already initialized by some "
134 << "other test in this run.";
135 return;
136 }
137 bool deleted = false;
138 DeletedMessageHandler* handler = new DeletedMessageHandler(&deleted);
139 delete handler;
140 EXPECT_TRUE(deleted);
141 EXPECT_FALSE(MessageQueueManager::IsInitialized());
142}