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_OK(close_cb_called); 51 uv_run(uv_default_loop(), UV_RUN_DEFAULT); 52 ASSERT_EQ(1, close_cb_called); 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_PTR_EQ(req, &shutdown_req); 73 shutdown_cb_called++; 74} 75 76 77static 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 84static 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 94static 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 102TEST_IMPL(ref) { 103 uv_run(uv_default_loop(), UV_RUN_DEFAULT); 104 MAKE_VALGRIND_HAPPY(uv_default_loop()); 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(uv_default_loop()); 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(uv_default_loop()); 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(uv_default_loop()); 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(uv_default_loop()); 152 return 0; 153} 154 155 156static void prepare_cb(uv_prepare_t* h) { 157 ASSERT_NOT_NULL(h); 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(uv_default_loop()); 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(uv_default_loop()); 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(uv_default_loop()); 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(uv_default_loop()); 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(uv_default_loop()); 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(uv_default_loop()); 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(uv_default_loop()); 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_EQ(1, close_cb_called); 254 MAKE_VALGRIND_HAPPY(uv_default_loop()); 255 return 0; 256} 257 258 259TEST_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 278TEST_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 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(uv_default_loop()); 305 return 0; 306} 307 308 309TEST_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 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_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 (uv_udp_send_cb) 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 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(uv_default_loop()); 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(uv_default_loop()); 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_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 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_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 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_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 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_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