2 * Copyright (C) 2015 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
29 #include <wtf/Vector.h>
30 #include <wtf/WorkQueue.h>
34 namespace TestWebKitAPI {
36 static const char* simpleTestLabel = "simpleTest";
37 static const char* longTestLabel = "longTest";
38 static const char* thirdTestLabel = "thirdTest";
39 static const char* dispatchAfterLabel = "dispatchAfter";
41 TEST(WTF_WorkQueue, Simple)
44 ThreadCondition m_testCompleted;
45 Vector<std::string> m_functionCallOrder;
47 bool calledSimpleTest = false;
48 bool calledLongTest = false;
49 bool calledThirdTest = false;
51 static const char* simpleTestLabel = "simpleTest";
52 static const char* longTestLabel = "longTest";
53 static const char* thirdTestLabel = "thirdTest";
55 auto queue = WorkQueue::create("com.apple.WebKit.Test.simple");
56 int initialRefCount = queue->refCount();
57 EXPECT_EQ(1, initialRefCount);
59 MutexLocker locker(m_lock);
60 queue->dispatch([&](void) {
61 m_functionCallOrder.append(simpleTestLabel);
62 calledSimpleTest = true;
65 queue->dispatch([&](void) {
66 m_functionCallOrder.append(longTestLabel);
67 std::this_thread::sleep_for(std::chrono::nanoseconds(100));
68 calledLongTest = true;
71 queue->dispatch([&](void) {
72 MutexLocker locker(m_lock);
73 m_functionCallOrder.append(thirdTestLabel);
74 calledThirdTest = true;
76 EXPECT_TRUE(calledSimpleTest);
77 EXPECT_TRUE(calledLongTest);
78 EXPECT_TRUE(calledThirdTest);
80 m_testCompleted.signal();
83 EXPECT_GT(queue->refCount(), 1);
85 m_testCompleted.wait(m_lock);
87 EXPECT_TRUE(calledSimpleTest);
88 EXPECT_TRUE(calledLongTest);
89 EXPECT_TRUE(calledThirdTest);
91 EXPECT_EQ(static_cast<size_t>(3), m_functionCallOrder.size());
92 EXPECT_STREQ(simpleTestLabel, m_functionCallOrder[0].c_str());
93 EXPECT_STREQ(longTestLabel, m_functionCallOrder[1].c_str());
94 EXPECT_STREQ(thirdTestLabel, m_functionCallOrder[2].c_str());
97 TEST(WTF_WorkQueue, TwoQueues)
100 ThreadCondition m_testQueue1Completed, m_testQueue2Completed;
101 Vector<std::string> m_functionCallOrder;
103 bool calledSimpleTest = false;
104 bool calledLongTest = false;
105 bool calledThirdTest = false;
107 auto queue1 = WorkQueue::create("com.apple.WebKit.Test.twoQueues1");
108 auto queue2 = WorkQueue::create("com.apple.WebKit.Test.twoQueues2");
110 EXPECT_EQ(1, queue1->refCount());
111 EXPECT_EQ(1, queue2->refCount());
113 MutexLocker locker(m_lock);
115 queue1->dispatch([&](void) {
116 m_functionCallOrder.append(simpleTestLabel);
117 calledSimpleTest = true;
120 queue2->dispatch([&](void) {
121 std::this_thread::sleep_for(std::chrono::milliseconds(50));
123 MutexLocker locker(m_lock);
125 // Will fail if queue2 took the mutex before queue1.
126 EXPECT_TRUE(calledThirdTest);
128 m_functionCallOrder.append(longTestLabel);
129 calledLongTest = true;
130 m_testQueue2Completed.signal();
133 queue1->dispatch([&](void) {
134 MutexLocker locker(m_lock);
135 m_functionCallOrder.append(thirdTestLabel);
136 calledThirdTest = true;
138 m_testQueue1Completed.signal();
141 m_testQueue1Completed.wait(m_lock);
143 EXPECT_TRUE(calledSimpleTest);
144 EXPECT_FALSE(calledLongTest);
145 EXPECT_TRUE(calledThirdTest);
147 m_testQueue2Completed.wait(m_lock);
149 EXPECT_TRUE(calledSimpleTest);
150 EXPECT_TRUE(calledLongTest);
151 EXPECT_TRUE(calledThirdTest);
153 EXPECT_EQ(static_cast<size_t>(3), m_functionCallOrder.size());
154 EXPECT_STREQ(simpleTestLabel, m_functionCallOrder[0].c_str());
155 EXPECT_STREQ(thirdTestLabel, m_functionCallOrder[1].c_str());
156 EXPECT_STREQ(longTestLabel, m_functionCallOrder[2].c_str());
159 TEST(WTF_WorkQueue, DispatchAfter)
162 ThreadCondition m_testCompleted, m_dispatchAfterTestCompleted;
163 Vector<std::string> m_functionCallOrder;
165 bool calledSimpleTest = false;
166 bool calledDispatchAfterTest = false;
168 auto queue = WorkQueue::create("com.apple.WebKit.Test.dispatchAfter");
170 MutexLocker locker(m_lock);
172 queue->dispatch([&](void) {
173 MutexLocker locker(m_lock);
174 m_functionCallOrder.append(simpleTestLabel);
175 calledSimpleTest = true;
176 m_testCompleted.signal();
179 queue->dispatchAfter(std::chrono::milliseconds(500), [&](void) {
180 MutexLocker locker(m_lock);
181 m_functionCallOrder.append(dispatchAfterLabel);
182 calledDispatchAfterTest = true;
183 m_dispatchAfterTestCompleted.signal();
186 m_testCompleted.wait(m_lock);
188 EXPECT_TRUE(calledSimpleTest);
189 EXPECT_FALSE(calledDispatchAfterTest);
191 m_dispatchAfterTestCompleted.wait(m_lock);
193 EXPECT_TRUE(calledSimpleTest);
194 EXPECT_TRUE(calledDispatchAfterTest);
196 EXPECT_EQ(static_cast<size_t>(2), m_functionCallOrder.size());
197 EXPECT_STREQ(simpleTestLabel, m_functionCallOrder[0].c_str());
198 EXPECT_STREQ(dispatchAfterLabel, m_functionCallOrder[1].c_str());
201 } // namespace TestWebKitAPI