Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : */
9 : /*
10 : * Timers are evil beasties across platforms ...
11 : */
12 :
13 : #include <test/bootstrapfixture.hxx>
14 :
15 : #include <osl/thread.hxx>
16 : #include <salhelper/thread.hxx>
17 :
18 : #include <vcl/timer.hxx>
19 : #include <vcl/svapp.hxx>
20 :
21 : /// Avoid our timer tests just wedging the build if they fail.
22 0 : class WatchDog : public osl::Thread
23 : {
24 : sal_Int32 mnSeconds;
25 : public:
26 2 : WatchDog(sal_Int32 nSeconds) :
27 : Thread(),
28 2 : mnSeconds( nSeconds )
29 : {
30 2 : create();
31 2 : }
32 2 : virtual void SAL_CALL run() SAL_OVERRIDE
33 : {
34 : TimeValue aWait;
35 2 : aWait.Seconds = mnSeconds;
36 2 : aWait.Nanosec = 1000000; // +1ms
37 2 : osl::Thread::wait( aWait );
38 0 : CPPUNIT_ASSERT_MESSAGE("watchdog triggered", false);
39 0 : }
40 : };
41 :
42 2 : static WatchDog aWatchDog( 10 /* 10 secs should be enough */);
43 :
44 16 : class TimerTest : public test::BootstrapFixture
45 : {
46 : public:
47 8 : TimerTest() : BootstrapFixture(true, false) {}
48 :
49 : #ifdef TEST_WATCHDOG
50 : void testWatchdog();
51 : #endif
52 : void testDurations();
53 : void testAutoTimer();
54 : void testRecursiveTimer();
55 : void testSlowTimerCallback();
56 :
57 4 : CPPUNIT_TEST_SUITE(TimerTest);
58 : #ifdef TEST_WATCHDOG
59 : CPPUNIT_TEST(testWatchdog);
60 : #endif
61 2 : CPPUNIT_TEST(testDurations);
62 2 : CPPUNIT_TEST(testAutoTimer);
63 2 : CPPUNIT_TEST(testRecursiveTimer);
64 2 : CPPUNIT_TEST(testSlowTimerCallback);
65 :
66 4 : CPPUNIT_TEST_SUITE_END();
67 : };
68 :
69 : #ifdef TEST_WATCHDOG
70 : void TimerTest::testWatchdog()
71 : {
72 : // out-wait the watchdog.
73 : TimeValue aWait;
74 : aWait.Seconds = 12;
75 : aWait.Nanosec = 0;
76 : osl::Thread::wait( aWait );
77 : }
78 : #endif
79 :
80 : // --------------------------------------------------------------------
81 :
82 8 : class TimerBool : public Timer
83 : {
84 : bool &mrBool;
85 : public:
86 8 : TimerBool( sal_uLong nMS, bool &rBool ) :
87 8 : Timer(), mrBool( rBool )
88 : {
89 8 : SetTimeout( nMS );
90 8 : Start();
91 8 : mrBool = false;
92 8 : }
93 8 : virtual void Timeout() SAL_OVERRIDE
94 : {
95 8 : mrBool = true;
96 8 : Application::EndYield();
97 8 : }
98 : };
99 :
100 2 : void TimerTest::testDurations()
101 : {
102 : static const sal_uLong aDurations[] = { 0, 1, 500, 1000 };
103 10 : for (size_t i = 0; i < SAL_N_ELEMENTS( aDurations ); i++)
104 : {
105 8 : bool bDone = false;
106 8 : TimerBool aTimer( aDurations[i], bDone );
107 : // coverity[infinite_loop]
108 46 : while( !bDone )
109 : {
110 30 : Application::Yield();
111 : }
112 8 : }
113 2 : }
114 :
115 : // --------------------------------------------------------------------
116 :
117 6 : class AutoTimerCount : public AutoTimer
118 : {
119 : sal_Int32 &mrCount;
120 : public:
121 6 : AutoTimerCount( sal_uLong nMS, sal_Int32 &rCount ) :
122 6 : AutoTimer(), mrCount( rCount )
123 : {
124 6 : SetTimeout( nMS );
125 6 : Start();
126 6 : mrCount = 0;
127 6 : }
128 703 : virtual void Timeout() SAL_OVERRIDE
129 : {
130 703 : mrCount++;
131 703 : }
132 : };
133 :
134 2 : void TimerTest::testAutoTimer()
135 : {
136 2 : sal_Int32 nCount = 0;
137 2 : AutoTimerCount aCount(1, nCount);
138 : // coverity[infinite_loop]
139 408 : while (nCount < 100) {
140 404 : Application::Yield();
141 2 : }
142 2 : }
143 :
144 : // --------------------------------------------------------------------
145 :
146 2 : class YieldTimer : public Timer
147 : {
148 : public:
149 2 : YieldTimer( sal_uLong nMS ) : Timer()
150 : {
151 2 : SetTimeout( nMS );
152 2 : Start();
153 2 : }
154 2 : virtual void Timeout() SAL_OVERRIDE
155 : {
156 202 : for (int i = 0; i < 100; i++)
157 200 : Application::Yield();
158 2 : }
159 : };
160 :
161 2 : void TimerTest::testRecursiveTimer()
162 : {
163 2 : sal_Int32 nCount = 0;
164 2 : YieldTimer aCount(5);
165 4 : AutoTimerCount aCountUp( 3, nCount );
166 : // coverity[infinite_loop]
167 17 : while (nCount < 20)
168 15 : Application::Yield();
169 2 : }
170 :
171 : // --------------------------------------------------------------------
172 :
173 2 : class SlowCallbackTimer : public Timer
174 : {
175 : bool &mbSlow;
176 : public:
177 2 : SlowCallbackTimer( sal_uLong nMS, bool &bBeenSlow ) :
178 2 : Timer(), mbSlow( bBeenSlow )
179 : {
180 2 : SetTimeout( nMS );
181 2 : Start();
182 2 : mbSlow = false;
183 2 : }
184 2 : virtual void Timeout() SAL_OVERRIDE
185 : {
186 : TimeValue aWait;
187 2 : aWait.Seconds = 1;
188 2 : aWait.Nanosec = 0;
189 2 : osl::Thread::wait( aWait );
190 2 : mbSlow = true;
191 2 : }
192 : };
193 :
194 2 : void TimerTest::testSlowTimerCallback()
195 : {
196 2 : bool bBeenSlow = false;
197 2 : sal_Int32 nCount = 0;
198 2 : AutoTimerCount aHighFreq(1, nCount);
199 4 : SlowCallbackTimer aSlow(250, bBeenSlow);
200 : // coverity[infinite_loop]
201 102098 : while (!bBeenSlow)
202 102094 : Application::Yield();
203 : // coverity[infinite_loop]
204 21 : while (nCount < 200)
205 19 : Application::Yield();
206 2 : }
207 :
208 2 : CPPUNIT_TEST_SUITE_REGISTRATION(TimerTest);
209 :
210 8 : CPPUNIT_PLUGIN_IMPLEMENT();
211 :
212 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|