1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to
5 * deal in the Software without restriction, including without limitation the
6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 * sell copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 * IN THE SOFTWARE.
20 */
21
22 #include "uv.h"
23 #include "task.h"
24
25
26 static int once_cb_called = 0;
27 static int once_close_cb_called = 0;
28 static int repeat_cb_called = 0;
29 static int repeat_close_cb_called = 0;
30 static int order_cb_called = 0;
31 static uint64_t start_time;
32 static uv_timer_t tiny_timer;
33 static uv_timer_t huge_timer1;
34 static uv_timer_t huge_timer2;
35
36
once_close_cb(uv_handle_t * handle)37 static void once_close_cb(uv_handle_t* handle) {
38 printf("ONCE_CLOSE_CB\n");
39
40 ASSERT(handle != NULL);
41 ASSERT(0 == uv_is_active(handle));
42
43 once_close_cb_called++;
44 }
45
46
once_cb(uv_timer_t * handle)47 static void once_cb(uv_timer_t* handle) {
48 printf("ONCE_CB %d\n", once_cb_called);
49
50 ASSERT(handle != NULL);
51 ASSERT(0 == uv_is_active((uv_handle_t*) handle));
52
53 once_cb_called++;
54
55 uv_close((uv_handle_t*)handle, once_close_cb);
56
57 /* Just call this randomly for the code coverage. */
58 uv_update_time(uv_default_loop());
59 }
60
61
repeat_close_cb(uv_handle_t * handle)62 static void repeat_close_cb(uv_handle_t* handle) {
63 printf("REPEAT_CLOSE_CB\n");
64
65 ASSERT(handle != NULL);
66
67 repeat_close_cb_called++;
68 }
69
70
repeat_cb(uv_timer_t * handle)71 static void repeat_cb(uv_timer_t* handle) {
72 printf("REPEAT_CB\n");
73
74 ASSERT(handle != NULL);
75 ASSERT(1 == uv_is_active((uv_handle_t*) handle));
76
77 repeat_cb_called++;
78
79 if (repeat_cb_called == 5) {
80 uv_close((uv_handle_t*)handle, repeat_close_cb);
81 }
82 }
83
84
never_cb(uv_timer_t * handle)85 static void never_cb(uv_timer_t* handle) {
86 FATAL("never_cb should never be called");
87 }
88
89
TEST_IMPL(timer)90 TEST_IMPL(timer) {
91 uv_timer_t once_timers[10];
92 uv_timer_t *once;
93 uv_timer_t repeat, never;
94 unsigned int i;
95 int r;
96
97 start_time = uv_now(uv_default_loop());
98 ASSERT(0 < start_time);
99
100 /* Let 10 timers time out in 500 ms total. */
101 for (i = 0; i < ARRAY_SIZE(once_timers); i++) {
102 once = once_timers + i;
103 r = uv_timer_init(uv_default_loop(), once);
104 ASSERT(r == 0);
105 r = uv_timer_start(once, once_cb, i * 50, 0);
106 ASSERT(r == 0);
107 }
108
109 /* The 11th timer is a repeating timer that runs 4 times */
110 r = uv_timer_init(uv_default_loop(), &repeat);
111 ASSERT(r == 0);
112 r = uv_timer_start(&repeat, repeat_cb, 100, 100);
113 ASSERT(r == 0);
114
115 /* The 12th timer should not do anything. */
116 r = uv_timer_init(uv_default_loop(), &never);
117 ASSERT(r == 0);
118 r = uv_timer_start(&never, never_cb, 100, 100);
119 ASSERT(r == 0);
120 r = uv_timer_stop(&never);
121 ASSERT(r == 0);
122 uv_unref((uv_handle_t*)&never);
123
124 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
125
126 ASSERT(once_cb_called == 10);
127 ASSERT(once_close_cb_called == 10);
128 printf("repeat_cb_called %d\n", repeat_cb_called);
129 ASSERT(repeat_cb_called == 5);
130 ASSERT(repeat_close_cb_called == 1);
131
132 ASSERT(500 <= uv_now(uv_default_loop()) - start_time);
133
134 MAKE_VALGRIND_HAPPY();
135 return 0;
136 }
137
138
TEST_IMPL(timer_start_twice)139 TEST_IMPL(timer_start_twice) {
140 uv_timer_t once;
141 int r;
142
143 r = uv_timer_init(uv_default_loop(), &once);
144 ASSERT(r == 0);
145 r = uv_timer_start(&once, never_cb, 86400 * 1000, 0);
146 ASSERT(r == 0);
147 r = uv_timer_start(&once, once_cb, 10, 0);
148 ASSERT(r == 0);
149 r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
150 ASSERT(r == 0);
151
152 ASSERT(once_cb_called == 1);
153
154 MAKE_VALGRIND_HAPPY();
155 return 0;
156 }
157
158
TEST_IMPL(timer_init)159 TEST_IMPL(timer_init) {
160 uv_timer_t handle;
161
162 ASSERT(0 == uv_timer_init(uv_default_loop(), &handle));
163 ASSERT(0 == uv_timer_get_repeat(&handle));
164 ASSERT(0 == uv_is_active((uv_handle_t*) &handle));
165
166 MAKE_VALGRIND_HAPPY();
167 return 0;
168 }
169
170
order_cb_a(uv_timer_t * handle)171 static void order_cb_a(uv_timer_t *handle) {
172 ASSERT(order_cb_called++ == *(int*)handle->data);
173 }
174
175
order_cb_b(uv_timer_t * handle)176 static void order_cb_b(uv_timer_t *handle) {
177 ASSERT(order_cb_called++ == *(int*)handle->data);
178 }
179
180
TEST_IMPL(timer_order)181 TEST_IMPL(timer_order) {
182 int first;
183 int second;
184 uv_timer_t handle_a;
185 uv_timer_t handle_b;
186
187 first = 0;
188 second = 1;
189 ASSERT(0 == uv_timer_init(uv_default_loop(), &handle_a));
190 ASSERT(0 == uv_timer_init(uv_default_loop(), &handle_b));
191
192 /* Test for starting handle_a then handle_b */
193 handle_a.data = &first;
194 ASSERT(0 == uv_timer_start(&handle_a, order_cb_a, 0, 0));
195 handle_b.data = &second;
196 ASSERT(0 == uv_timer_start(&handle_b, order_cb_b, 0, 0));
197 ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
198
199 ASSERT(order_cb_called == 2);
200
201 ASSERT(0 == uv_timer_stop(&handle_a));
202 ASSERT(0 == uv_timer_stop(&handle_b));
203
204 /* Test for starting handle_b then handle_a */
205 order_cb_called = 0;
206 handle_b.data = &first;
207 ASSERT(0 == uv_timer_start(&handle_b, order_cb_b, 0, 0));
208
209 handle_a.data = &second;
210 ASSERT(0 == uv_timer_start(&handle_a, order_cb_a, 0, 0));
211 ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
212
213 ASSERT(order_cb_called == 2);
214
215 MAKE_VALGRIND_HAPPY();
216 return 0;
217 }
218
219
tiny_timer_cb(uv_timer_t * handle)220 static void tiny_timer_cb(uv_timer_t* handle) {
221 ASSERT(handle == &tiny_timer);
222 uv_close((uv_handle_t*) &tiny_timer, NULL);
223 uv_close((uv_handle_t*) &huge_timer1, NULL);
224 uv_close((uv_handle_t*) &huge_timer2, NULL);
225 }
226
227
TEST_IMPL(timer_huge_timeout)228 TEST_IMPL(timer_huge_timeout) {
229 ASSERT(0 == uv_timer_init(uv_default_loop(), &tiny_timer));
230 ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer1));
231 ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer2));
232 ASSERT(0 == uv_timer_start(&tiny_timer, tiny_timer_cb, 1, 0));
233 ASSERT(0 == uv_timer_start(&huge_timer1, tiny_timer_cb, 0xffffffffffffLL, 0));
234 ASSERT(0 == uv_timer_start(&huge_timer2, tiny_timer_cb, (uint64_t) -1, 0));
235 ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
236 MAKE_VALGRIND_HAPPY();
237 return 0;
238 }
239
240
huge_repeat_cb(uv_timer_t * handle)241 static void huge_repeat_cb(uv_timer_t* handle) {
242 static int ncalls;
243
244 if (ncalls == 0)
245 ASSERT(handle == &huge_timer1);
246 else
247 ASSERT(handle == &tiny_timer);
248
249 if (++ncalls == 10) {
250 uv_close((uv_handle_t*) &tiny_timer, NULL);
251 uv_close((uv_handle_t*) &huge_timer1, NULL);
252 }
253 }
254
255
TEST_IMPL(timer_huge_repeat)256 TEST_IMPL(timer_huge_repeat) {
257 ASSERT(0 == uv_timer_init(uv_default_loop(), &tiny_timer));
258 ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer1));
259 ASSERT(0 == uv_timer_start(&tiny_timer, huge_repeat_cb, 2, 2));
260 ASSERT(0 == uv_timer_start(&huge_timer1, huge_repeat_cb, 1, (uint64_t) -1));
261 ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
262 MAKE_VALGRIND_HAPPY();
263 return 0;
264 }
265
266
267 static unsigned int timer_run_once_timer_cb_called;
268
269
timer_run_once_timer_cb(uv_timer_t * handle)270 static void timer_run_once_timer_cb(uv_timer_t* handle) {
271 timer_run_once_timer_cb_called++;
272 }
273
274
TEST_IMPL(timer_run_once)275 TEST_IMPL(timer_run_once) {
276 uv_timer_t timer_handle;
277
278 ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle));
279 ASSERT(0 == uv_timer_start(&timer_handle, timer_run_once_timer_cb, 0, 0));
280 ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
281 ASSERT(1 == timer_run_once_timer_cb_called);
282
283 ASSERT(0 == uv_timer_start(&timer_handle, timer_run_once_timer_cb, 1, 0));
284 ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
285 ASSERT(2 == timer_run_once_timer_cb_called);
286
287 uv_close((uv_handle_t*) &timer_handle, NULL);
288 ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
289
290 MAKE_VALGRIND_HAPPY();
291 return 0;
292 }
293
294
TEST_IMPL(timer_is_closing)295 TEST_IMPL(timer_is_closing) {
296 uv_timer_t handle;
297
298 ASSERT(0 == uv_timer_init(uv_default_loop(), &handle));
299 uv_close((uv_handle_t *)&handle, NULL);
300
301 ASSERT(UV_EINVAL == uv_timer_start(&handle, never_cb, 100, 100));
302
303 MAKE_VALGRIND_HAPPY();
304 return 0;
305 }
306
307
TEST_IMPL(timer_null_callback)308 TEST_IMPL(timer_null_callback) {
309 uv_timer_t handle;
310
311 ASSERT(0 == uv_timer_init(uv_default_loop(), &handle));
312 ASSERT(UV_EINVAL == uv_timer_start(&handle, NULL, 100, 100));
313
314 MAKE_VALGRIND_HAPPY();
315 return 0;
316 }
317
318
319 static uint64_t timer_early_check_expected_time;
320
321
timer_early_check_cb(uv_timer_t * handle)322 static void timer_early_check_cb(uv_timer_t* handle) {
323 uint64_t hrtime = uv_hrtime() / 1000000;
324 ASSERT(hrtime >= timer_early_check_expected_time);
325 }
326
327
TEST_IMPL(timer_early_check)328 TEST_IMPL(timer_early_check) {
329 uv_timer_t timer_handle;
330 const uint64_t timeout_ms = 10;
331
332 timer_early_check_expected_time = uv_now(uv_default_loop()) + timeout_ms;
333
334 ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle));
335 ASSERT(0 == uv_timer_start(&timer_handle, timer_early_check_cb, timeout_ms, 0));
336 ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
337
338 uv_close((uv_handle_t*) &timer_handle, NULL);
339 ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
340
341 MAKE_VALGRIND_HAPPY();
342 return 0;
343 }
344