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 close_cb_called = 0; |
27 | static int repeat_1_cb_called = 0; |
28 | static int repeat_2_cb_called = 0; |
29 | |
30 | static int repeat_2_cb_allowed = 0; |
31 | |
32 | static uv_timer_t dummy, repeat_1, repeat_2; |
33 | |
34 | static uint64_t start_time; |
35 | |
36 | |
37 | static void close_cb(uv_handle_t* handle) { |
38 | ASSERT(handle != NULL); |
39 | |
40 | close_cb_called++; |
41 | } |
42 | |
43 | |
44 | static void repeat_1_cb(uv_timer_t* handle) { |
45 | int r; |
46 | |
47 | ASSERT(handle == &repeat_1); |
48 | ASSERT(uv_timer_get_repeat((uv_timer_t*)handle) == 50); |
49 | |
50 | fprintf(stderr, "repeat_1_cb called after %ld ms\n" , |
51 | (long int)(uv_now(uv_default_loop()) - start_time)); |
52 | fflush(stderr); |
53 | |
54 | repeat_1_cb_called++; |
55 | |
56 | r = uv_timer_again(&repeat_2); |
57 | ASSERT(r == 0); |
58 | |
59 | if (repeat_1_cb_called == 10) { |
60 | uv_close((uv_handle_t*)handle, close_cb); |
61 | /* We're not calling uv_timer_again on repeat_2 any more, so after this |
62 | * timer_2_cb is expected. */ |
63 | repeat_2_cb_allowed = 1; |
64 | return; |
65 | } |
66 | } |
67 | |
68 | |
69 | static void repeat_2_cb(uv_timer_t* handle) { |
70 | ASSERT(handle == &repeat_2); |
71 | ASSERT(repeat_2_cb_allowed); |
72 | |
73 | fprintf(stderr, "repeat_2_cb called after %ld ms\n" , |
74 | (long int)(uv_now(uv_default_loop()) - start_time)); |
75 | fflush(stderr); |
76 | |
77 | repeat_2_cb_called++; |
78 | |
79 | if (uv_timer_get_repeat(&repeat_2) == 0) { |
80 | ASSERT(0 == uv_is_active((uv_handle_t*) handle)); |
81 | uv_close((uv_handle_t*)handle, close_cb); |
82 | return; |
83 | } |
84 | |
85 | fprintf(stderr, "uv_timer_get_repeat %ld ms\n" , |
86 | (long int)uv_timer_get_repeat(&repeat_2)); |
87 | fflush(stderr); |
88 | ASSERT(uv_timer_get_repeat(&repeat_2) == 100); |
89 | |
90 | /* This shouldn't take effect immediately. */ |
91 | uv_timer_set_repeat(&repeat_2, 0); |
92 | } |
93 | |
94 | |
95 | TEST_IMPL(timer_again) { |
96 | int r; |
97 | |
98 | start_time = uv_now(uv_default_loop()); |
99 | ASSERT(0 < start_time); |
100 | |
101 | /* Verify that it is not possible to uv_timer_again a never-started timer. */ |
102 | r = uv_timer_init(uv_default_loop(), &dummy); |
103 | ASSERT(r == 0); |
104 | r = uv_timer_again(&dummy); |
105 | ASSERT(r == UV_EINVAL); |
106 | uv_unref((uv_handle_t*)&dummy); |
107 | |
108 | /* Start timer repeat_1. */ |
109 | r = uv_timer_init(uv_default_loop(), &repeat_1); |
110 | ASSERT(r == 0); |
111 | r = uv_timer_start(&repeat_1, repeat_1_cb, 50, 0); |
112 | ASSERT(r == 0); |
113 | ASSERT(uv_timer_get_repeat(&repeat_1) == 0); |
114 | |
115 | /* Actually make repeat_1 repeating. */ |
116 | uv_timer_set_repeat(&repeat_1, 50); |
117 | ASSERT(uv_timer_get_repeat(&repeat_1) == 50); |
118 | |
119 | /* |
120 | * Start another repeating timer. It'll be again()ed by the repeat_1 so |
121 | * it should not time out until repeat_1 stops. |
122 | */ |
123 | r = uv_timer_init(uv_default_loop(), &repeat_2); |
124 | ASSERT(r == 0); |
125 | r = uv_timer_start(&repeat_2, repeat_2_cb, 100, 100); |
126 | ASSERT(r == 0); |
127 | ASSERT(uv_timer_get_repeat(&repeat_2) == 100); |
128 | |
129 | uv_run(uv_default_loop(), UV_RUN_DEFAULT); |
130 | |
131 | ASSERT(repeat_1_cb_called == 10); |
132 | ASSERT(repeat_2_cb_called == 2); |
133 | ASSERT(close_cb_called == 2); |
134 | |
135 | fprintf(stderr, "Test took %ld ms (expected ~700 ms)\n" , |
136 | (long int)(uv_now(uv_default_loop()) - start_time)); |
137 | fflush(stderr); |
138 | |
139 | MAKE_VALGRIND_HAPPY(); |
140 | return 0; |
141 | } |
142 | |