• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 uint64_t start_time;
34 static uv_timer_t tiny_timer;
35 static uv_timer_t huge_timer1;
36 static uv_timer_t huge_timer2;
37 
38 
once_close_cb(uv_handle_t * handle)39 static 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 
once_cb(uv_timer_t * handle)49 static 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 
twice_close_cb(uv_handle_t * handle)63 static 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 
twice_cb(uv_timer_t * handle)72 static 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 
repeat_close_cb(uv_handle_t * handle)85 static 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 
repeat_cb(uv_timer_t * handle)94 static 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 
never_cb(uv_timer_t * handle)108 static void never_cb(uv_timer_t* handle) {
109   FATAL("never_cb should never be called");
110 }
111 
112 
TEST_IMPL(timer)113 TEST_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 
TEST_IMPL(timer_start_twice)162 TEST_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 
TEST_IMPL(timer_init)182 TEST_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 
order_cb_a(uv_timer_t * handle)195 static void order_cb_a(uv_timer_t *handle) {
196   ASSERT(order_cb_called++ == *(int*)handle->data);
197 }
198 
199 
order_cb_b(uv_timer_t * handle)200 static void order_cb_b(uv_timer_t *handle) {
201   ASSERT(order_cb_called++ == *(int*)handle->data);
202 }
203 
204 
TEST_IMPL(timer_order)205 TEST_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 
tiny_timer_cb(uv_timer_t * handle)244 static 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 
TEST_IMPL(timer_huge_timeout)252 TEST_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 
huge_repeat_cb(uv_timer_t * handle)268 static 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 
TEST_IMPL(timer_huge_repeat)283 TEST_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 
294 static unsigned int timer_run_once_timer_cb_called;
295 
296 
timer_run_once_timer_cb(uv_timer_t * handle)297 static void timer_run_once_timer_cb(uv_timer_t* handle) {
298   timer_run_once_timer_cb_called++;
299 }
300 
301 
TEST_IMPL(timer_run_once)302 TEST_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 
TEST_IMPL(timer_is_closing)322 TEST_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 
TEST_IMPL(timer_null_callback)335 TEST_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 
346 static uint64_t timer_early_check_expected_time;
347 
348 
timer_early_check_cb(uv_timer_t * handle)349 static 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 
TEST_IMPL(timer_early_check)355 TEST_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