xref: /libuv/test/test-ref.c (revision 9b3b61f6)
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 
29 static uv_write_t write_req;
30 static uv_shutdown_t shutdown_req;
31 static uv_connect_t connect_req;
32 
33 static char buffer[32767];
34 
35 static int req_cb_called;
36 static int connect_cb_called;
37 static int write_cb_called;
38 static int shutdown_cb_called;
39 static int close_cb_called;
40 
41 
close_cb(uv_handle_t * handle)42 static void close_cb(uv_handle_t* handle) {
43   close_cb_called++;
44 }
45 
46 
do_close(void * handle)47 static void do_close(void* handle) {
48   close_cb_called = 0;
49   uv_close((uv_handle_t*)handle, close_cb);
50   ASSERT_OK(close_cb_called);
51   uv_run(uv_default_loop(), UV_RUN_DEFAULT);
52   ASSERT_EQ(1, close_cb_called);
53 }
54 
55 
fail_cb(void)56 static void fail_cb(void) {
57   FATAL("fail_cb should not have been called");
58 }
59 
60 
fail_cb2(void)61 static void fail_cb2(void) {
62   ASSERT(0 && "fail_cb2 should not have been called");
63 }
64 
65 
req_cb(uv_udp_send_t * req,int status)66 static void req_cb(uv_udp_send_t* req, int status) {
67   req_cb_called++;
68 }
69 
70 
shutdown_cb(uv_shutdown_t * req,int status)71 static void shutdown_cb(uv_shutdown_t* req, int status) {
72   ASSERT_PTR_EQ(req, &shutdown_req);
73   shutdown_cb_called++;
74 }
75 
76 
write_cb(uv_write_t * req,int status)77 static void write_cb(uv_write_t* req, int status) {
78   ASSERT_PTR_EQ(req, &write_req);
79   uv_shutdown(&shutdown_req, req->handle, shutdown_cb);
80   write_cb_called++;
81 }
82 
83 
connect_and_write(uv_connect_t * req,int status)84 static void connect_and_write(uv_connect_t* req, int status) {
85   uv_buf_t buf = uv_buf_init(buffer, sizeof buffer);
86   ASSERT_PTR_EQ(req, &connect_req);
87   ASSERT_OK(status);
88   uv_write(&write_req, req->handle, &buf, 1, write_cb);
89   connect_cb_called++;
90 }
91 
92 
93 
connect_and_shutdown(uv_connect_t * req,int status)94 static void connect_and_shutdown(uv_connect_t* req, int status) {
95   ASSERT_PTR_EQ(req, &connect_req);
96   ASSERT_OK(status);
97   uv_shutdown(&shutdown_req, req->handle, shutdown_cb);
98   connect_cb_called++;
99 }
100 
101 
TEST_IMPL(ref)102 TEST_IMPL(ref) {
103   uv_run(uv_default_loop(), UV_RUN_DEFAULT);
104   MAKE_VALGRIND_HAPPY(uv_default_loop());
105   return 0;
106 }
107 
108 
TEST_IMPL(idle_ref)109 TEST_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(uv_default_loop());
117   return 0;
118 }
119 
120 
TEST_IMPL(async_ref)121 TEST_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(uv_default_loop());
128   return 0;
129 }
130 
131 
TEST_IMPL(prepare_ref)132 TEST_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(uv_default_loop());
140   return 0;
141 }
142 
143 
TEST_IMPL(check_ref)144 TEST_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(uv_default_loop());
152   return 0;
153 }
154 
155 
prepare_cb(uv_prepare_t * h)156 static void prepare_cb(uv_prepare_t* h) {
157   ASSERT_NOT_NULL(h);
158   uv_unref((uv_handle_t*)h);
159 }
160 
161 
TEST_IMPL(unref_in_prepare_cb)162 TEST_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(uv_default_loop());
169   return 0;
170 }
171 
172 
TEST_IMPL(timer_ref)173 TEST_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(uv_default_loop());
180   return 0;
181 }
182 
183 
TEST_IMPL(timer_ref2)184 TEST_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(uv_default_loop());
192   return 0;
193 }
194 
195 
TEST_IMPL(fs_event_ref)196 TEST_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(uv_default_loop());
207   return 0;
208 }
209 
210 
TEST_IMPL(fs_poll_ref)211 TEST_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(uv_default_loop());
219   return 0;
220 }
221 
222 
TEST_IMPL(tcp_ref)223 TEST_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(uv_default_loop());
230   return 0;
231 }
232 
233 
TEST_IMPL(tcp_ref2)234 TEST_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(uv_default_loop());
242   return 0;
243 }
244 
245 
TEST_IMPL(tcp_ref2b)246 TEST_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_EQ(1, close_cb_called);
254   MAKE_VALGRIND_HAPPY(uv_default_loop());
255   return 0;
256 }
257 
258 
TEST_IMPL(tcp_ref3)259 TEST_IMPL(tcp_ref3) {
260   struct sockaddr_in addr;
261   uv_tcp_t h;
262   ASSERT_OK(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_EQ(1, connect_cb_called);
271   ASSERT_EQ(1, shutdown_cb_called);
272   do_close(&h);
273   MAKE_VALGRIND_HAPPY(uv_default_loop());
274   return 0;
275 }
276 
277 
TEST_IMPL(tcp_ref4)278 TEST_IMPL(tcp_ref4) {
279   struct sockaddr_in addr;
280   uv_tcp_t h;
281   ASSERT_OK(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_EQ(1, connect_cb_called);
290   ASSERT_EQ(1, write_cb_called);
291   ASSERT_EQ(1, shutdown_cb_called);
292   do_close(&h);
293   MAKE_VALGRIND_HAPPY(uv_default_loop());
294   return 0;
295 }
296 
297 
TEST_IMPL(udp_ref)298 TEST_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(uv_default_loop());
305   return 0;
306 }
307 
308 
TEST_IMPL(udp_ref2)309 TEST_IMPL(udp_ref2) {
310   struct sockaddr_in addr;
311   uv_udp_t h;
312   ASSERT_OK(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(uv_default_loop());
320   return 0;
321 }
322 
323 
TEST_IMPL(udp_ref3)324 TEST_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_OK(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               req_cb);
338   uv_unref((uv_handle_t*)&h);
339   uv_run(uv_default_loop(), UV_RUN_DEFAULT);
340   ASSERT_EQ(1, req_cb_called);
341   do_close(&h);
342 
343   MAKE_VALGRIND_HAPPY(uv_default_loop());
344   return 0;
345 }
346 
347 
TEST_IMPL(pipe_ref)348 TEST_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(uv_default_loop());
355   return 0;
356 }
357 
358 
TEST_IMPL(pipe_ref2)359 TEST_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(uv_default_loop());
367   return 0;
368 }
369 
370 
TEST_IMPL(pipe_ref3)371 TEST_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_EQ(1, connect_cb_called);
378   ASSERT_EQ(1, shutdown_cb_called);
379   do_close(&h);
380   MAKE_VALGRIND_HAPPY(uv_default_loop());
381   return 0;
382 }
383 
384 
TEST_IMPL(pipe_ref4)385 TEST_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_EQ(1, connect_cb_called);
392   ASSERT_EQ(1, write_cb_called);
393   ASSERT_EQ(1, shutdown_cb_called);
394   do_close(&h);
395   MAKE_VALGRIND_HAPPY(uv_default_loop());
396   return 0;
397 }
398 
399 
TEST_IMPL(process_ref)400 TEST_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_OK(r);
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_OK(r);
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_OK(r);
428 
429   do_close(&h);
430 
431   MAKE_VALGRIND_HAPPY(uv_default_loop());
432   return 0;
433 }
434 
435 
TEST_IMPL(has_ref)436 TEST_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_EQ(1, uv_has_ref((uv_handle_t*)&h));
441   uv_unref((uv_handle_t*)&h);
442   ASSERT_OK(uv_has_ref((uv_handle_t*)&h));
443   MAKE_VALGRIND_HAPPY(uv_default_loop());
444   return 0;
445 }
446