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