|
160
|
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 #include <string.h>
|
|
|
26
|
|
|
27 #define FIXTURE "testfile"
|
|
|
28
|
|
|
29 static void timer_cb(uv_timer_t* handle);
|
|
|
30 static void close_cb(uv_handle_t* handle);
|
|
|
31 static void poll_cb(uv_fs_poll_t* handle,
|
|
|
32 int status,
|
|
|
33 const uv_stat_t* prev,
|
|
|
34 const uv_stat_t* curr);
|
|
|
35
|
|
|
36 static void poll_cb_fail(uv_fs_poll_t* handle,
|
|
|
37 int status,
|
|
|
38 const uv_stat_t* prev,
|
|
|
39 const uv_stat_t* curr);
|
|
|
40 static void poll_cb_noop(uv_fs_poll_t* handle,
|
|
|
41 int status,
|
|
|
42 const uv_stat_t* prev,
|
|
|
43 const uv_stat_t* curr);
|
|
|
44
|
|
|
45 static uv_fs_poll_t poll_handle;
|
|
|
46 static uv_timer_t timer_handle;
|
|
|
47 static uv_loop_t* loop;
|
|
|
48
|
|
|
49 static int poll_cb_called;
|
|
|
50 static int timer_cb_called;
|
|
|
51 static int close_cb_called;
|
|
|
52
|
|
|
53
|
|
|
54 static void touch_file(const char* path) {
|
|
|
55 static int count;
|
|
|
56 FILE* fp;
|
|
|
57 int i;
|
|
|
58
|
|
|
59 ASSERT((fp = fopen(FIXTURE, "w+")));
|
|
|
60
|
|
|
61 /* Need to change the file size because the poller may not pick up
|
|
|
62 * sub-second mtime changes.
|
|
|
63 */
|
|
|
64 i = ++count;
|
|
|
65
|
|
|
66 while (i--)
|
|
|
67 fputc('*', fp);
|
|
|
68
|
|
|
69 fclose(fp);
|
|
|
70 }
|
|
|
71
|
|
|
72
|
|
|
73 static void close_cb(uv_handle_t* handle) {
|
|
|
74 close_cb_called++;
|
|
|
75 }
|
|
|
76
|
|
|
77
|
|
|
78 static void timer_cb(uv_timer_t* handle) {
|
|
|
79 touch_file(FIXTURE);
|
|
|
80 timer_cb_called++;
|
|
|
81 }
|
|
|
82
|
|
|
83
|
|
|
84 static void poll_cb_fail(uv_fs_poll_t* handle,
|
|
|
85 int status,
|
|
|
86 const uv_stat_t* prev,
|
|
|
87 const uv_stat_t* curr) {
|
|
|
88 ASSERT(0 && "fail_cb called");
|
|
|
89 }
|
|
|
90
|
|
|
91 static void poll_cb_noop(uv_fs_poll_t* handle,
|
|
|
92 int status,
|
|
|
93 const uv_stat_t* prev,
|
|
|
94 const uv_stat_t* curr) {
|
|
|
95 }
|
|
|
96
|
|
|
97
|
|
|
98 static void poll_cb(uv_fs_poll_t* handle,
|
|
|
99 int status,
|
|
|
100 const uv_stat_t* prev,
|
|
|
101 const uv_stat_t* curr) {
|
|
|
102 uv_stat_t zero_statbuf;
|
|
|
103
|
|
|
104 memset(&zero_statbuf, 0, sizeof(zero_statbuf));
|
|
|
105
|
|
|
106 ASSERT_PTR_EQ(handle, &poll_handle);
|
|
|
107 ASSERT_EQ(1, uv_is_active((uv_handle_t*) handle));
|
|
|
108 ASSERT_NOT_NULL(prev);
|
|
|
109 ASSERT_NOT_NULL(curr);
|
|
|
110
|
|
|
111 switch (poll_cb_called++) {
|
|
|
112 case 0:
|
|
|
113 ASSERT_EQ(status, UV_ENOENT);
|
|
|
114 ASSERT_OK(memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
|
|
|
115 ASSERT_OK(memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
|
|
|
116 touch_file(FIXTURE);
|
|
|
117 break;
|
|
|
118
|
|
|
119 case 1:
|
|
|
120 ASSERT_OK(status);
|
|
|
121 ASSERT_OK(memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
|
|
|
122 ASSERT_NE(0, memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
|
|
|
123 ASSERT_OK(uv_timer_start(&timer_handle, timer_cb, 20, 0));
|
|
|
124 break;
|
|
|
125
|
|
|
126 case 2:
|
|
|
127 ASSERT_OK(status);
|
|
|
128 ASSERT_NE(0, memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
|
|
|
129 ASSERT_NE(0, memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
|
|
|
130 ASSERT_OK(uv_timer_start(&timer_handle, timer_cb, 200, 0));
|
|
|
131 break;
|
|
|
132
|
|
|
133 case 3:
|
|
|
134 ASSERT_OK(status);
|
|
|
135 ASSERT_NE(0, memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
|
|
|
136 ASSERT_NE(0, memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
|
|
|
137 remove(FIXTURE);
|
|
|
138 break;
|
|
|
139
|
|
|
140 case 4:
|
|
|
141 ASSERT_EQ(status, UV_ENOENT);
|
|
|
142 ASSERT_NE(0, memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
|
|
|
143 ASSERT_OK(memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
|
|
|
144 uv_close((uv_handle_t*)handle, close_cb);
|
|
|
145 break;
|
|
|
146
|
|
|
147 default:
|
|
|
148 ASSERT(0);
|
|
|
149 }
|
|
|
150 }
|
|
|
151
|
|
|
152
|
|
|
153 TEST_IMPL(fs_poll) {
|
|
|
154 loop = uv_default_loop();
|
|
|
155
|
|
|
156 remove(FIXTURE);
|
|
|
157
|
|
|
158 ASSERT_OK(uv_timer_init(loop, &timer_handle));
|
|
|
159 ASSERT_OK(uv_fs_poll_init(loop, &poll_handle));
|
|
|
160 ASSERT_OK(uv_fs_poll_start(&poll_handle, poll_cb, FIXTURE, 100));
|
|
|
161 ASSERT_OK(uv_run(loop, UV_RUN_DEFAULT));
|
|
|
162
|
|
|
163 ASSERT_EQ(5, poll_cb_called);
|
|
|
164 ASSERT_EQ(2, timer_cb_called);
|
|
|
165 ASSERT_EQ(1, close_cb_called);
|
|
|
166
|
|
|
167 MAKE_VALGRIND_HAPPY(loop);
|
|
|
168 return 0;
|
|
|
169 }
|
|
|
170
|
|
|
171
|
|
|
172 TEST_IMPL(fs_poll_getpath) {
|
|
|
173 char buf[1024];
|
|
|
174 size_t len;
|
|
|
175 loop = uv_default_loop();
|
|
|
176
|
|
|
177 remove(FIXTURE);
|
|
|
178
|
|
|
179 ASSERT_OK(uv_fs_poll_init(loop, &poll_handle));
|
|
|
180 len = sizeof buf;
|
|
|
181 ASSERT_EQ(UV_EINVAL, uv_fs_poll_getpath(&poll_handle, buf, &len));
|
|
|
182 ASSERT_OK(uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100));
|
|
|
183 len = sizeof buf;
|
|
|
184 ASSERT_OK(uv_fs_poll_getpath(&poll_handle, buf, &len));
|
|
|
185 ASSERT_NE(0, buf[len - 1]);
|
|
|
186 ASSERT_EQ(buf[len], '\0');
|
|
|
187 ASSERT_OK(memcmp(buf, FIXTURE, len));
|
|
|
188
|
|
|
189 uv_close((uv_handle_t*) &poll_handle, close_cb);
|
|
|
190
|
|
|
191 ASSERT_OK(uv_run(loop, UV_RUN_DEFAULT));
|
|
|
192
|
|
|
193 ASSERT_EQ(1, close_cb_called);
|
|
|
194
|
|
|
195 MAKE_VALGRIND_HAPPY(loop);
|
|
|
196 return 0;
|
|
|
197 }
|
|
|
198
|
|
|
199
|
|
|
200 TEST_IMPL(fs_poll_close_request) {
|
|
|
201 uv_loop_t loop;
|
|
|
202 uv_fs_poll_t poll_handle;
|
|
|
203
|
|
|
204 remove(FIXTURE);
|
|
|
205
|
|
|
206 ASSERT_OK(uv_loop_init(&loop));
|
|
|
207
|
|
|
208 ASSERT_OK(uv_fs_poll_init(&loop, &poll_handle));
|
|
|
209 ASSERT_OK(uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100));
|
|
|
210 uv_close((uv_handle_t*) &poll_handle, close_cb);
|
|
|
211 while (close_cb_called == 0)
|
|
|
212 uv_run(&loop, UV_RUN_ONCE);
|
|
|
213 ASSERT_EQ(1, close_cb_called);
|
|
|
214
|
|
|
215 MAKE_VALGRIND_HAPPY(&loop);
|
|
|
216 return 0;
|
|
|
217 }
|
|
|
218
|
|
|
219 TEST_IMPL(fs_poll_close_request_multi_start_stop) {
|
|
|
220 uv_loop_t loop;
|
|
|
221 uv_fs_poll_t poll_handle;
|
|
|
222 int i;
|
|
|
223
|
|
|
224 remove(FIXTURE);
|
|
|
225
|
|
|
226 ASSERT_OK(uv_loop_init(&loop));
|
|
|
227
|
|
|
228 ASSERT_OK(uv_fs_poll_init(&loop, &poll_handle));
|
|
|
229
|
|
|
230 for (i = 0; i < 10; ++i) {
|
|
|
231 ASSERT_OK(uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100));
|
|
|
232 ASSERT_OK(uv_fs_poll_stop(&poll_handle));
|
|
|
233 }
|
|
|
234 uv_close((uv_handle_t*) &poll_handle, close_cb);
|
|
|
235 while (close_cb_called == 0)
|
|
|
236 uv_run(&loop, UV_RUN_ONCE);
|
|
|
237 ASSERT_EQ(1, close_cb_called);
|
|
|
238
|
|
|
239 MAKE_VALGRIND_HAPPY(&loop);
|
|
|
240 return 0;
|
|
|
241 }
|
|
|
242
|
|
|
243 TEST_IMPL(fs_poll_close_request_multi_stop_start) {
|
|
|
244 uv_loop_t loop;
|
|
|
245 uv_fs_poll_t poll_handle;
|
|
|
246 int i;
|
|
|
247
|
|
|
248 remove(FIXTURE);
|
|
|
249
|
|
|
250 ASSERT_OK(uv_loop_init(&loop));
|
|
|
251
|
|
|
252 ASSERT_OK(uv_fs_poll_init(&loop, &poll_handle));
|
|
|
253
|
|
|
254 for (i = 0; i < 10; ++i) {
|
|
|
255 ASSERT_OK(uv_fs_poll_stop(&poll_handle));
|
|
|
256 ASSERT_OK(uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100));
|
|
|
257 }
|
|
|
258 uv_close((uv_handle_t*) &poll_handle, close_cb);
|
|
|
259 while (close_cb_called == 0)
|
|
|
260 uv_run(&loop, UV_RUN_ONCE);
|
|
|
261 ASSERT_EQ(1, close_cb_called);
|
|
|
262
|
|
|
263 MAKE_VALGRIND_HAPPY(&loop);
|
|
|
264 return 0;
|
|
|
265 }
|
|
|
266
|
|
|
267 TEST_IMPL(fs_poll_close_request_stop_when_active) {
|
|
|
268 /* Regression test for https://github.com/libuv/libuv/issues/2287. */
|
|
|
269 uv_loop_t loop;
|
|
|
270 uv_fs_poll_t poll_handle;
|
|
|
271
|
|
|
272 remove(FIXTURE);
|
|
|
273
|
|
|
274 ASSERT_OK(uv_loop_init(&loop));
|
|
|
275
|
|
|
276 /* Set up all handles. */
|
|
|
277 ASSERT_OK(uv_fs_poll_init(&loop, &poll_handle));
|
|
|
278 ASSERT_OK(uv_fs_poll_start(&poll_handle, poll_cb_noop, FIXTURE, 100));
|
|
|
279 uv_run(&loop, UV_RUN_ONCE);
|
|
|
280
|
|
|
281 /* Close the timer handle, and do not crash. */
|
|
|
282 ASSERT_OK(uv_fs_poll_stop(&poll_handle));
|
|
|
283 uv_run(&loop, UV_RUN_ONCE);
|
|
|
284
|
|
|
285 /* Clean up after the test. */
|
|
|
286 uv_close((uv_handle_t*) &poll_handle, close_cb);
|
|
|
287 uv_run(&loop, UV_RUN_ONCE);
|
|
|
288 ASSERT_EQ(1, close_cb_called);
|
|
|
289
|
|
|
290 MAKE_VALGRIND_HAPPY(&loop);
|
|
|
291 return 0;
|
|
|
292 }
|