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 twice_cb_called = 0;
29 static int twice_close_cb_called = 0;
30 static int repeat_cb_called = 0;
31 static int repeat_close_cb_called = 0;
32 static int order_cb_called = 0;
33 static int timer_check_double_call_called = 0;
34 static int zero_timeout_cb_calls = 0;
35 static uint64_t start_time;
36 static uv_timer_t tiny_timer;
37 static uv_timer_t huge_timer1;
38 static uv_timer_t huge_timer2;
39
40
once_close_cb(uv_handle_t * handle)41 static void once_close_cb(uv_handle_t* handle) {
42 printf("ONCE_CLOSE_CB\n");
43
44 ASSERT_NOT_NULL(handle);
45 ASSERT_OK(uv_is_active(handle));
46
47 once_close_cb_called++;
48 }
49
50
once_cb(uv_timer_t * handle)51 static void once_cb(uv_timer_t* handle) {
52 printf("ONCE_CB %d\n", once_cb_called);
53
54 ASSERT_NOT_NULL(handle);
55 ASSERT_OK(uv_is_active((uv_handle_t*) handle));
56
57 once_cb_called++;
58
59 uv_close((uv_handle_t*)handle, once_close_cb);
60
61 /* Just call this randomly for the code coverage. */
62 uv_update_time(uv_default_loop());
63 }
64
twice_close_cb(uv_handle_t * handle)65 static void twice_close_cb(uv_handle_t* handle) {
66 printf("TWICE_CLOSE_CB\n");
67
68 ASSERT_NOT_NULL(handle);
69 ASSERT_OK(uv_is_active(handle));
70
71 twice_close_cb_called++;
72 }
73
twice_cb(uv_timer_t * handle)74 static void twice_cb(uv_timer_t* handle) {
75 printf("TWICE_CB %d\n", twice_cb_called);
76
77 ASSERT_NOT_NULL(handle);
78 ASSERT_OK(uv_is_active((uv_handle_t*) handle));
79
80 twice_cb_called++;
81
82 uv_close((uv_handle_t*)handle, twice_close_cb);
83 }
84
85
86
repeat_close_cb(uv_handle_t * handle)87 static void repeat_close_cb(uv_handle_t* handle) {
88 printf("REPEAT_CLOSE_CB\n");
89
90 ASSERT_NOT_NULL(handle);
91
92 repeat_close_cb_called++;
93 }
94
95
repeat_cb(uv_timer_t * handle)96 static void repeat_cb(uv_timer_t* handle) {
97 printf("REPEAT_CB\n");
98
99 ASSERT_NOT_NULL(handle);
100 ASSERT_EQ(1, uv_is_active((uv_handle_t*) handle));
101
102 repeat_cb_called++;
103
104 if (repeat_cb_called == 5) {
105 uv_close((uv_handle_t*)handle, repeat_close_cb);
106 }
107 }
108
109
never_cb(uv_timer_t * handle)110 static void never_cb(uv_timer_t* handle) {
111 FATAL("never_cb should never be called");
112 }
113
114
TEST_IMPL(timer)115 TEST_IMPL(timer) {
116 uv_timer_t once_timers[10];
117 uv_timer_t *once;
118 uv_timer_t repeat, never;
119 unsigned int i;
120 int r;
121
122 start_time = uv_now(uv_default_loop());
123 ASSERT_LT(0, start_time);
124
125 /* Let 10 timers time out in 500 ms total. */
126 for (i = 0; i < ARRAY_SIZE(once_timers); i++) {
127 once = once_timers + i;
128 r = uv_timer_init(uv_default_loop(), once);
129 ASSERT_OK(r);
130 r = uv_timer_start(once, once_cb, i * 50, 0);
131 ASSERT_OK(r);
132 }
133
134 /* The 11th timer is a repeating timer that runs 4 times */
135 r = uv_timer_init(uv_default_loop(), &repeat);
136 ASSERT_OK(r);
137 r = uv_timer_start(&repeat, repeat_cb, 100, 100);
138 ASSERT_OK(r);
139
140 /* The 12th timer should not do anything. */
141 r = uv_timer_init(uv_default_loop(), &never);
142 ASSERT_OK(r);
143 r = uv_timer_start(&never, never_cb, 100, 100);
144 ASSERT_OK(r);
145 r = uv_timer_stop(&never);
146 ASSERT_OK(r);
147 uv_unref((uv_handle_t*)&never);
148
149 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
150
151 ASSERT_EQ(10, once_cb_called);
152 ASSERT_EQ(10, once_close_cb_called);
153 printf("repeat_cb_called %d\n", repeat_cb_called);
154 ASSERT_EQ(5, repeat_cb_called);
155 ASSERT_EQ(1, repeat_close_cb_called);
156
157 ASSERT_LE(500, uv_now(uv_default_loop()) - start_time);
158
159 MAKE_VALGRIND_HAPPY(uv_default_loop());
160 return 0;
161 }
162
163
TEST_IMPL(timer_start_twice)164 TEST_IMPL(timer_start_twice) {
165 uv_timer_t once;
166 int r;
167
168 r = uv_timer_init(uv_default_loop(), &once);
169 ASSERT_OK(r);
170 r = uv_timer_start(&once, never_cb, 86400 * 1000, 0);
171 ASSERT_OK(r);
172 r = uv_timer_start(&once, twice_cb, 10, 0);
173 ASSERT_OK(r);
174 r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
175 ASSERT_OK(r);
176
177 ASSERT_EQ(1, twice_cb_called);
178
179 MAKE_VALGRIND_HAPPY(uv_default_loop());
180 return 0;
181 }
182
183
TEST_IMPL(timer_init)184 TEST_IMPL(timer_init) {
185 uv_timer_t handle;
186
187 ASSERT_OK(uv_timer_init(uv_default_loop(), &handle));
188 ASSERT_OK(uv_timer_get_repeat(&handle));
189 ASSERT_UINT64_LE(0, uv_timer_get_due_in(&handle));
190 ASSERT_OK(uv_is_active((uv_handle_t*) &handle));
191
192 MAKE_VALGRIND_HAPPY(uv_default_loop());
193 return 0;
194 }
195
196
order_cb_a(uv_timer_t * handle)197 static void order_cb_a(uv_timer_t *handle) {
198 ASSERT_EQ(order_cb_called++, *(int*)handle->data);
199 }
200
201
order_cb_b(uv_timer_t * handle)202 static void order_cb_b(uv_timer_t *handle) {
203 ASSERT_EQ(order_cb_called++, *(int*)handle->data);
204 }
205
206
TEST_IMPL(timer_order)207 TEST_IMPL(timer_order) {
208 int first;
209 int second;
210 uv_timer_t handle_a;
211 uv_timer_t handle_b;
212
213 first = 0;
214 second = 1;
215 ASSERT_OK(uv_timer_init(uv_default_loop(), &handle_a));
216 ASSERT_OK(uv_timer_init(uv_default_loop(), &handle_b));
217
218 /* Test for starting handle_a then handle_b */
219 handle_a.data = &first;
220 ASSERT_OK(uv_timer_start(&handle_a, order_cb_a, 0, 0));
221 handle_b.data = &second;
222 ASSERT_OK(uv_timer_start(&handle_b, order_cb_b, 0, 0));
223 ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
224
225 ASSERT_EQ(2, order_cb_called);
226
227 ASSERT_OK(uv_timer_stop(&handle_a));
228 ASSERT_OK(uv_timer_stop(&handle_b));
229
230 /* Test for starting handle_b then handle_a */
231 order_cb_called = 0;
232 handle_b.data = &first;
233 ASSERT_OK(uv_timer_start(&handle_b, order_cb_b, 0, 0));
234
235 handle_a.data = &second;
236 ASSERT_OK(uv_timer_start(&handle_a, order_cb_a, 0, 0));
237 ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
238
239 ASSERT_EQ(2, order_cb_called);
240
241 MAKE_VALGRIND_HAPPY(uv_default_loop());
242 return 0;
243 }
244
245
zero_timeout_cb(uv_timer_t * handle)246 static void zero_timeout_cb(uv_timer_t* handle) {
247 ASSERT_OK(uv_timer_start(handle, zero_timeout_cb, 0, 0));
248 uv_stop(handle->loop);
249 zero_timeout_cb_calls++;
250 }
251
252
TEST_IMPL(timer_zero_timeout)253 TEST_IMPL(timer_zero_timeout) {
254 uv_timer_t timer;
255 uv_loop_t* loop;
256
257 loop = uv_default_loop();
258 ASSERT_OK(uv_timer_init(loop, &timer));
259 ASSERT_OK(uv_timer_start(&timer, zero_timeout_cb, 0, 0));
260 ASSERT_EQ(1, uv_run(loop, UV_RUN_DEFAULT)); /* because of uv_stop() */
261 ASSERT_EQ(1, zero_timeout_cb_calls);
262 uv_close((uv_handle_t*) &timer, NULL);
263 ASSERT_OK(uv_run(loop, UV_RUN_DEFAULT));
264 ASSERT_EQ(1, zero_timeout_cb_calls);
265
266 MAKE_VALGRIND_HAPPY(loop);
267 return 0;
268 }
269
270
tiny_timer_cb(uv_timer_t * handle)271 static void tiny_timer_cb(uv_timer_t* handle) {
272 ASSERT_PTR_EQ(handle, &tiny_timer);
273 uv_close((uv_handle_t*) &tiny_timer, NULL);
274 uv_close((uv_handle_t*) &huge_timer1, NULL);
275 uv_close((uv_handle_t*) &huge_timer2, NULL);
276 }
277
278
TEST_IMPL(timer_huge_timeout)279 TEST_IMPL(timer_huge_timeout) {
280 ASSERT_OK(uv_timer_init(uv_default_loop(), &tiny_timer));
281 ASSERT_OK(uv_timer_init(uv_default_loop(), &huge_timer1));
282 ASSERT_OK(uv_timer_init(uv_default_loop(), &huge_timer2));
283 ASSERT_OK(uv_timer_start(&tiny_timer, tiny_timer_cb, 1, 0));
284 ASSERT_OK(uv_timer_start(&huge_timer1,
285 tiny_timer_cb,
286 0xffffffffffffLL,
287 0));
288 ASSERT_OK(uv_timer_start(&huge_timer2, tiny_timer_cb, (uint64_t) -1, 0));
289 ASSERT_UINT64_EQ(1, uv_timer_get_due_in(&tiny_timer));
290 ASSERT_UINT64_EQ(281474976710655, uv_timer_get_due_in(&huge_timer1));
291 ASSERT_UINT64_LE(0, uv_timer_get_due_in(&huge_timer2));
292 ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
293 MAKE_VALGRIND_HAPPY(uv_default_loop());
294 return 0;
295 }
296
297
huge_repeat_cb(uv_timer_t * handle)298 static void huge_repeat_cb(uv_timer_t* handle) {
299 static int ncalls;
300
301 if (ncalls == 0)
302 ASSERT_PTR_EQ(handle, &huge_timer1);
303 else
304 ASSERT_PTR_EQ(handle, &tiny_timer);
305
306 if (++ncalls == 10) {
307 uv_close((uv_handle_t*) &tiny_timer, NULL);
308 uv_close((uv_handle_t*) &huge_timer1, NULL);
309 }
310 }
311
312
TEST_IMPL(timer_huge_repeat)313 TEST_IMPL(timer_huge_repeat) {
314 ASSERT_OK(uv_timer_init(uv_default_loop(), &tiny_timer));
315 ASSERT_OK(uv_timer_init(uv_default_loop(), &huge_timer1));
316 ASSERT_OK(uv_timer_start(&tiny_timer, huge_repeat_cb, 2, 2));
317 ASSERT_OK(uv_timer_start(&huge_timer1, huge_repeat_cb, 1, (uint64_t) -1));
318 ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
319 MAKE_VALGRIND_HAPPY(uv_default_loop());
320 return 0;
321 }
322
323
324 static unsigned int timer_run_once_timer_cb_called;
325
326
timer_run_once_timer_cb(uv_timer_t * handle)327 static void timer_run_once_timer_cb(uv_timer_t* handle) {
328 timer_run_once_timer_cb_called++;
329 }
330
331
TEST_IMPL(timer_run_once)332 TEST_IMPL(timer_run_once) {
333 uv_timer_t timer_handle;
334
335 ASSERT_OK(uv_timer_init(uv_default_loop(), &timer_handle));
336 ASSERT_OK(uv_timer_start(&timer_handle, timer_run_once_timer_cb, 0, 0));
337 ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_ONCE));
338 ASSERT_EQ(1, timer_run_once_timer_cb_called);
339
340 ASSERT_OK(uv_timer_start(&timer_handle, timer_run_once_timer_cb, 1, 0));
341 ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_ONCE));
342 ASSERT_EQ(2, timer_run_once_timer_cb_called);
343
344 uv_close((uv_handle_t*) &timer_handle, NULL);
345 ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_ONCE));
346
347 MAKE_VALGRIND_HAPPY(uv_default_loop());
348 return 0;
349 }
350
351
TEST_IMPL(timer_is_closing)352 TEST_IMPL(timer_is_closing) {
353 uv_timer_t handle;
354
355 ASSERT_OK(uv_timer_init(uv_default_loop(), &handle));
356 uv_close((uv_handle_t *)&handle, NULL);
357
358 ASSERT_EQ(UV_EINVAL, uv_timer_start(&handle, never_cb, 100, 100));
359
360 MAKE_VALGRIND_HAPPY(uv_default_loop());
361 return 0;
362 }
363
364
TEST_IMPL(timer_null_callback)365 TEST_IMPL(timer_null_callback) {
366 uv_timer_t handle;
367
368 ASSERT_OK(uv_timer_init(uv_default_loop(), &handle));
369 ASSERT_EQ(UV_EINVAL, uv_timer_start(&handle, NULL, 100, 100));
370
371 MAKE_VALGRIND_HAPPY(uv_default_loop());
372 return 0;
373 }
374
375
376 static uint64_t timer_early_check_expected_time;
377
378
timer_early_check_cb(uv_timer_t * handle)379 static void timer_early_check_cb(uv_timer_t* handle) {
380 uint64_t hrtime = uv_hrtime() / 1000000;
381 ASSERT_GE(hrtime, timer_early_check_expected_time);
382 }
383
384
TEST_IMPL(timer_early_check)385 TEST_IMPL(timer_early_check) {
386 uv_timer_t timer_handle;
387 const uint64_t timeout_ms = 10;
388
389 timer_early_check_expected_time = uv_now(uv_default_loop()) + timeout_ms;
390
391 ASSERT_OK(uv_timer_init(uv_default_loop(), &timer_handle));
392 ASSERT_OK(uv_timer_start(&timer_handle,
393 timer_early_check_cb,
394 timeout_ms,
395 0));
396 ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
397
398 uv_close((uv_handle_t*) &timer_handle, NULL);
399 ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
400
401 MAKE_VALGRIND_HAPPY(uv_default_loop());
402 return 0;
403 }
404
timer_check_double_call(uv_timer_t * handle)405 static void timer_check_double_call(uv_timer_t* handle) {
406 timer_check_double_call_called++;
407 }
408
TEST_IMPL(timer_no_double_call_once)409 TEST_IMPL(timer_no_double_call_once) {
410 uv_timer_t timer_handle;
411 const uint64_t timeout_ms = 10;
412
413 ASSERT_OK(uv_timer_init(uv_default_loop(), &timer_handle));
414 ASSERT_OK(uv_timer_start(&timer_handle,
415 timer_check_double_call,
416 timeout_ms,
417 timeout_ms));
418 uv_sleep(timeout_ms * 2);
419 ASSERT_EQ(1, uv_run(uv_default_loop(), UV_RUN_ONCE));
420 ASSERT_EQ(1, timer_check_double_call_called);
421
422 MAKE_VALGRIND_HAPPY(uv_default_loop());
423 return 0;
424 }
425
TEST_IMPL(timer_no_double_call_nowait)426 TEST_IMPL(timer_no_double_call_nowait) {
427 uv_timer_t timer_handle;
428 const uint64_t timeout_ms = 10;
429
430 ASSERT_OK(uv_timer_init(uv_default_loop(), &timer_handle));
431 ASSERT_OK(uv_timer_start(&timer_handle,
432 timer_check_double_call,
433 timeout_ms,
434 timeout_ms));
435 uv_sleep(timeout_ms * 2);
436 ASSERT_EQ(1, uv_run(uv_default_loop(), UV_RUN_NOWAIT));
437 ASSERT_EQ(1, timer_check_double_call_called);
438
439 MAKE_VALGRIND_HAPPY(uv_default_loop());
440 return 0;
441 }
442
TEST_IMPL(timer_no_run_on_unref)443 TEST_IMPL(timer_no_run_on_unref) {
444 uv_timer_t timer_handle;
445
446 ASSERT_OK(uv_timer_init(uv_default_loop(), &timer_handle));
447 ASSERT_OK(uv_timer_start(&timer_handle, (uv_timer_cb) abort, 0, 0));
448 uv_unref((uv_handle_t*) &timer_handle);
449 ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
450
451 MAKE_VALGRIND_HAPPY(uv_default_loop());
452 return 0;
453 }
454