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