1/*
2 * Copyright (C) 2015 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
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.
12 *
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.
24 */
25
26#include "config.h"
27
28#include "Utilities.h"
29#include <wtf/RunLoop.h>
30#include <wtf/Threading.h>
31
32namespace TestWebKitAPI {
33
34static bool testFinished;
35static int count = 100;
36
37TEST(WTF_RunLoop, Deadlock)
38{
39 RunLoop::initializeMainRunLoop();
40
41 struct DispatchFromDestructorTester {
42 ~DispatchFromDestructorTester() {
43 RunLoop::main().dispatch([] {
44 if (!(--count))
45 testFinished = true;
46 });
47 }
48 };
49
50 for (int i = 0; i < count; ++i) {
51 auto capture = std::make_shared<DispatchFromDestructorTester>();
52 RunLoop::main().dispatch([capture] { });
53 }
54
55 Util::run(&testFinished);
56}
57
58class DerivedOneShotTimer : public RunLoop::Timer<DerivedOneShotTimer> {
59public:
60 DerivedOneShotTimer(bool& testFinished)
61 : RunLoop::Timer<DerivedOneShotTimer>(RunLoop::current(), this, &DerivedOneShotTimer::fired)
62 , m_testFinished(testFinished)
63 {
64 }
65
66 void fired()
67 {
68 m_testFinished = true;
69 stop();
70 }
71
72private:
73 bool& m_testFinished;
74};
75
76
77TEST(WTF_RunLoop, OneShotTimer)
78{
79 RunLoop::initializeMainRunLoop();
80
81 bool testFinished = false;
82 DerivedOneShotTimer timer(testFinished);
83 timer.startOneShot(100_ms);
84 Util::run(&testFinished);
85}
86
87class DerivedRepeatingTimer : public RunLoop::Timer<DerivedRepeatingTimer> {
88public:
89 DerivedRepeatingTimer(bool& testFinished)
90 : RunLoop::Timer<DerivedRepeatingTimer>(RunLoop::current(), this, &DerivedRepeatingTimer::fired)
91 , m_testFinished(testFinished)
92 {
93 }
94
95 void fired()
96 {
97 if (++m_count == 10) {
98 m_testFinished = true;
99 stop();
100 }
101 }
102
103private:
104 unsigned m_count { 0 };
105 bool& m_testFinished;
106};
107
108
109TEST(WTF_RunLoop, RepeatingTimer)
110{
111 RunLoop::initializeMainRunLoop();
112
113 bool testFinished = false;
114 DerivedRepeatingTimer timer(testFinished);
115 timer.startRepeating(10_ms);
116 Util::run(&testFinished);
117 ASSERT_FALSE(timer.isActive());
118}
119
120TEST(WTF_RunLoop, ManyTimes)
121{
122 class Counter {
123 public:
124 void run()
125 {
126 if (++m_count == 100000) {
127 RunLoop::current().stop();
128 return;
129 }
130 RunLoop::current().dispatch([this] {
131 run();
132 });
133 }
134
135 private:
136 unsigned m_count { 0 };
137 };
138
139 Thread::create("RunLoopManyTimes", [] {
140 Counter counter;
141 RunLoop::current().dispatch([&counter] {
142 counter.run();
143 });
144 RunLoop::run();
145 })->waitForCompletion();
146}
147
148} // namespace TestWebKitAPI
149