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 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 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 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 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 85 static void never_cb(uv_timer_t* handle) { 86 FATAL("never_cb should never be called"); 87 } 88 89 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 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 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 171 static void order_cb_a(uv_timer_t *handle) { 172 ASSERT(order_cb_called++ == *(int*)handle->data); 173 } 174 175 176 static void order_cb_b(uv_timer_t *handle) { 177 ASSERT(order_cb_called++ == *(int*)handle->data); 178 } 179 180 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 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 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 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 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 270 static void timer_run_once_timer_cb(uv_timer_t* handle) { 271 timer_run_once_timer_cb_called++; 272 } 273 274 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 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 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 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 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