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 <stdlib.h>
26#include <string.h>
27
28
29static uv_write_t write_req;
30static uv_shutdown_t shutdown_req;
31static uv_connect_t connect_req;
32
33static char buffer[32767];
34
35static int req_cb_called;
36static int connect_cb_called;
37static int write_cb_called;
38static int shutdown_cb_called;
39static int close_cb_called;
40
41
42static void close_cb(uv_handle_t* handle) {
43 close_cb_called++;
44}
45
46
47static void do_close(void* handle) {
48 close_cb_called = 0;
49 uv_close((uv_handle_t*)handle, close_cb);
50 ASSERT(close_cb_called == 0);
51 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
52 ASSERT(close_cb_called == 1);
53}
54
55
56static void fail_cb(void) {
57 FATAL("fail_cb should not have been called");
58}
59
60
61static void fail_cb2(void) {
62 ASSERT(0 && "fail_cb2 should not have been called");
63}
64
65
66static void req_cb(uv_handle_t* req, int status) {
67 req_cb_called++;
68}
69
70
71static void shutdown_cb(uv_shutdown_t* req, int status) {
72 ASSERT(req == &shutdown_req);
73 shutdown_cb_called++;
74}
75
76
77static void write_cb(uv_write_t* req, int status) {
78 ASSERT(req == &write_req);
79 uv_shutdown(&shutdown_req, req->handle, shutdown_cb);
80 write_cb_called++;
81}
82
83
84static void connect_and_write(uv_connect_t* req, int status) {
85 uv_buf_t buf = uv_buf_init(buffer, sizeof buffer);
86 ASSERT(req == &connect_req);
87 ASSERT(status == 0);
88 uv_write(&write_req, req->handle, &buf, 1, write_cb);
89 connect_cb_called++;
90}
91
92
93
94static void connect_and_shutdown(uv_connect_t* req, int status) {
95 ASSERT(req == &connect_req);
96 ASSERT(status == 0);
97 uv_shutdown(&shutdown_req, req->handle, shutdown_cb);
98 connect_cb_called++;
99}
100
101
102TEST_IMPL(ref) {
103 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
104 MAKE_VALGRIND_HAPPY();
105 return 0;
106}
107
108
109TEST_IMPL(idle_ref) {
110 uv_idle_t h;
111 uv_idle_init(uv_default_loop(), &h);
112 uv_idle_start(&h, (uv_idle_cb) fail_cb2);
113 uv_unref((uv_handle_t*)&h);
114 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
115 do_close(&h);
116 MAKE_VALGRIND_HAPPY();
117 return 0;
118}
119
120
121TEST_IMPL(async_ref) {
122 uv_async_t h;
123 uv_async_init(uv_default_loop(), &h, NULL);
124 uv_unref((uv_handle_t*)&h);
125 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
126 do_close(&h);
127 MAKE_VALGRIND_HAPPY();
128 return 0;
129}
130
131
132TEST_IMPL(prepare_ref) {
133 uv_prepare_t h;
134 uv_prepare_init(uv_default_loop(), &h);
135 uv_prepare_start(&h, (uv_prepare_cb) fail_cb2);
136 uv_unref((uv_handle_t*)&h);
137 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
138 do_close(&h);
139 MAKE_VALGRIND_HAPPY();
140 return 0;
141}
142
143
144TEST_IMPL(check_ref) {
145 uv_check_t h;
146 uv_check_init(uv_default_loop(), &h);
147 uv_check_start(&h, (uv_check_cb) fail_cb2);
148 uv_unref((uv_handle_t*)&h);
149 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
150 do_close(&h);
151 MAKE_VALGRIND_HAPPY();
152 return 0;
153}
154
155
156static void prepare_cb(uv_prepare_t* h) {
157 ASSERT(h != NULL);
158 uv_unref((uv_handle_t*)h);
159}
160
161
162TEST_IMPL(unref_in_prepare_cb) {
163 uv_prepare_t h;
164 uv_prepare_init(uv_default_loop(), &h);
165 uv_prepare_start(&h, prepare_cb);
166 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
167 do_close(&h);
168 MAKE_VALGRIND_HAPPY();
169 return 0;
170}
171
172
173TEST_IMPL(timer_ref) {
174 uv_timer_t h;
175 uv_timer_init(uv_default_loop(), &h);
176 uv_unref((uv_handle_t*)&h);
177 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
178 do_close(&h);
179 MAKE_VALGRIND_HAPPY();
180 return 0;
181}
182
183
184TEST_IMPL(timer_ref2) {
185 uv_timer_t h;
186 uv_timer_init(uv_default_loop(), &h);
187 uv_timer_start(&h, (uv_timer_cb)fail_cb, 42, 42);
188 uv_unref((uv_handle_t*)&h);
189 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
190 do_close(&h);
191 MAKE_VALGRIND_HAPPY();
192 return 0;
193}
194
195
196TEST_IMPL(fs_event_ref) {
197#if defined(NO_FS_EVENTS)
198 RETURN_SKIP(NO_FS_EVENTS);
199#endif
200 uv_fs_event_t h;
201 uv_fs_event_init(uv_default_loop(), &h);
202 uv_fs_event_start(&h, (uv_fs_event_cb)fail_cb, ".", 0);
203 uv_unref((uv_handle_t*)&h);
204 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
205 do_close(&h);
206 MAKE_VALGRIND_HAPPY();
207 return 0;
208}
209
210
211TEST_IMPL(fs_poll_ref) {
212 uv_fs_poll_t h;
213 uv_fs_poll_init(uv_default_loop(), &h);
214 uv_fs_poll_start(&h, NULL, ".", 999);
215 uv_unref((uv_handle_t*)&h);
216 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
217 do_close(&h);
218 MAKE_VALGRIND_HAPPY();
219 return 0;
220}
221
222
223TEST_IMPL(tcp_ref) {
224 uv_tcp_t h;
225 uv_tcp_init(uv_default_loop(), &h);
226 uv_unref((uv_handle_t*)&h);
227 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
228 do_close(&h);
229 MAKE_VALGRIND_HAPPY();
230 return 0;
231}
232
233
234TEST_IMPL(tcp_ref2) {
235 uv_tcp_t h;
236 uv_tcp_init(uv_default_loop(), &h);
237 uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
238 uv_unref((uv_handle_t*)&h);
239 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
240 do_close(&h);
241 MAKE_VALGRIND_HAPPY();
242 return 0;
243}
244
245
246TEST_IMPL(tcp_ref2b) {
247 uv_tcp_t h;
248 uv_tcp_init(uv_default_loop(), &h);
249 uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
250 uv_unref((uv_handle_t*)&h);
251 uv_close((uv_handle_t*)&h, close_cb);
252 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
253 ASSERT(close_cb_called == 1);
254 MAKE_VALGRIND_HAPPY();
255 return 0;
256}
257
258
259TEST_IMPL(tcp_ref3) {
260 struct sockaddr_in addr;
261 uv_tcp_t h;
262 ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
263 uv_tcp_init(uv_default_loop(), &h);
264 uv_tcp_connect(&connect_req,
265 &h,
266 (const struct sockaddr*) &addr,
267 connect_and_shutdown);
268 uv_unref((uv_handle_t*)&h);
269 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
270 ASSERT(connect_cb_called == 1);
271 ASSERT(shutdown_cb_called == 1);
272 do_close(&h);
273 MAKE_VALGRIND_HAPPY();
274 return 0;
275}
276
277
278TEST_IMPL(tcp_ref4) {
279 struct sockaddr_in addr;
280 uv_tcp_t h;
281 ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
282 uv_tcp_init(uv_default_loop(), &h);
283 uv_tcp_connect(&connect_req,
284 &h,
285 (const struct sockaddr*) &addr,
286 connect_and_write);
287 uv_unref((uv_handle_t*)&h);
288 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
289 ASSERT(connect_cb_called == 1);
290 ASSERT(write_cb_called == 1);
291 ASSERT(shutdown_cb_called == 1);
292 do_close(&h);
293 MAKE_VALGRIND_HAPPY();
294 return 0;
295}
296
297
298TEST_IMPL(udp_ref) {
299 uv_udp_t h;
300 uv_udp_init(uv_default_loop(), &h);
301 uv_unref((uv_handle_t*)&h);
302 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
303 do_close(&h);
304 MAKE_VALGRIND_HAPPY();
305 return 0;
306}
307
308
309TEST_IMPL(udp_ref2) {
310 struct sockaddr_in addr;
311 uv_udp_t h;
312 ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
313 uv_udp_init(uv_default_loop(), &h);
314 uv_udp_bind(&h, (const struct sockaddr*) &addr, 0);
315 uv_udp_recv_start(&h, (uv_alloc_cb)fail_cb, (uv_udp_recv_cb)fail_cb);
316 uv_unref((uv_handle_t*)&h);
317 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
318 do_close(&h);
319 MAKE_VALGRIND_HAPPY();
320 return 0;
321}
322
323
324TEST_IMPL(udp_ref3) {
325 struct sockaddr_in addr;
326 uv_buf_t buf = uv_buf_init("PING", 4);
327 uv_udp_send_t req;
328 uv_udp_t h;
329
330 ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
331 uv_udp_init(uv_default_loop(), &h);
332 uv_udp_send(&req,
333 &h,
334 &buf,
335 1,
336 (const struct sockaddr*) &addr,
337 (uv_udp_send_cb) req_cb);
338 uv_unref((uv_handle_t*)&h);
339 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
340 ASSERT(req_cb_called == 1);
341 do_close(&h);
342
343 MAKE_VALGRIND_HAPPY();
344 return 0;
345}
346
347
348TEST_IMPL(pipe_ref) {
349 uv_pipe_t h;
350 uv_pipe_init(uv_default_loop(), &h, 0);
351 uv_unref((uv_handle_t*)&h);
352 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
353 do_close(&h);
354 MAKE_VALGRIND_HAPPY();
355 return 0;
356}
357
358
359TEST_IMPL(pipe_ref2) {
360 uv_pipe_t h;
361 uv_pipe_init(uv_default_loop(), &h, 0);
362 uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
363 uv_unref((uv_handle_t*)&h);
364 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
365 do_close(&h);
366 MAKE_VALGRIND_HAPPY();
367 return 0;
368}
369
370
371TEST_IMPL(pipe_ref3) {
372 uv_pipe_t h;
373 uv_pipe_init(uv_default_loop(), &h, 0);
374 uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_and_shutdown);
375 uv_unref((uv_handle_t*)&h);
376 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
377 ASSERT(connect_cb_called == 1);
378 ASSERT(shutdown_cb_called == 1);
379 do_close(&h);
380 MAKE_VALGRIND_HAPPY();
381 return 0;
382}
383
384
385TEST_IMPL(pipe_ref4) {
386 uv_pipe_t h;
387 uv_pipe_init(uv_default_loop(), &h, 0);
388 uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_and_write);
389 uv_unref((uv_handle_t*)&h);
390 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
391 ASSERT(connect_cb_called == 1);
392 ASSERT(write_cb_called == 1);
393 ASSERT(shutdown_cb_called == 1);
394 do_close(&h);
395 MAKE_VALGRIND_HAPPY();
396 return 0;
397}
398
399
400TEST_IMPL(process_ref) {
401 /* spawn_helper4 blocks indefinitely. */
402 char *argv[] = { NULL, "spawn_helper4", NULL };
403 uv_process_options_t options;
404 size_t exepath_size;
405 char exepath[256];
406 uv_process_t h;
407 int r;
408
409 memset(&options, 0, sizeof(options));
410 exepath_size = sizeof(exepath);
411
412 r = uv_exepath(exepath, &exepath_size);
413 ASSERT(r == 0);
414
415 argv[0] = exepath;
416 options.file = exepath;
417 options.args = argv;
418 options.exit_cb = NULL;
419
420 r = uv_spawn(uv_default_loop(), &h, &options);
421 ASSERT(r == 0);
422
423 uv_unref((uv_handle_t*)&h);
424 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
425
426 r = uv_process_kill(&h, /* SIGTERM */ 15);
427 ASSERT(r == 0);
428
429 do_close(&h);
430
431 MAKE_VALGRIND_HAPPY();
432 return 0;
433}
434
435
436TEST_IMPL(has_ref) {
437 uv_idle_t h;
438 uv_idle_init(uv_default_loop(), &h);
439 uv_ref((uv_handle_t*)&h);
440 ASSERT(uv_has_ref((uv_handle_t*)&h) == 1);
441 uv_unref((uv_handle_t*)&h);
442 ASSERT(uv_has_ref((uv_handle_t*)&h) == 0);
443 MAKE_VALGRIND_HAPPY();
444 return 0;
445}
446