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 26static int once_cb_called = 0; 27static int once_close_cb_called = 0; 28static int twice_cb_called = 0; 29static int twice_close_cb_called = 0; 30static int repeat_cb_called = 0; 31static int repeat_close_cb_called = 0; 32static int order_cb_called = 0; 33static int timer_check_double_call_called = 0; 34static int zero_timeout_cb_calls = 0; 35static uint64_t start_time; 36static uv_timer_t tiny_timer; 37static uv_timer_t huge_timer1; 38static uv_timer_t huge_timer2; 39 40 41static 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 51static 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 65static 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 74static 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 87static 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 96static 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 110static void never_cb(uv_timer_t* handle) { 111 FATAL("never_cb should never be called"); 112} 113 114 115TEST_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 164TEST_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 184TEST_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 197static void order_cb_a(uv_timer_t *handle) { 198 ASSERT_EQ(order_cb_called++, *(int*)handle->data); 199} 200 201 202static void order_cb_b(uv_timer_t *handle) { 203 ASSERT_EQ(order_cb_called++, *(int*)handle->data); 204} 205 206 207TEST_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 246static 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 253TEST_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 271static 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 279TEST_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 298static 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 313TEST_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 324static unsigned int timer_run_once_timer_cb_called; 325 326 327static void timer_run_once_timer_cb(uv_timer_t* handle) { 328 timer_run_once_timer_cb_called++; 329} 330 331 332TEST_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 352TEST_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 365TEST_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 376static uint64_t timer_early_check_expected_time; 377 378 379static 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 385TEST_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 405static void timer_check_double_call(uv_timer_t* handle) { 406 timer_check_double_call_called++; 407} 408 409TEST_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 426TEST_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 443TEST_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