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 42 static void close_cb(uv_handle_t* handle) { 43 close_cb_called++; 44 } 45 46 47 static 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 56 static void fail_cb(void) { 57 FATAL("fail_cb should not have been called"); 58 } 59 60 61 static void fail_cb2(void) { 62 ASSERT(0 && "fail_cb2 should not have been called"); 63 } 64 65 66 static void req_cb(uv_handle_t* req, int status) { 67 req_cb_called++; 68 } 69 70 71 static void shutdown_cb(uv_shutdown_t* req, int status) { 72 ASSERT(req == &shutdown_req); 73 shutdown_cb_called++; 74 } 75 76 77 static 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 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(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 94 static 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 102 TEST_IMPL(ref) { 103 uv_run(uv_default_loop(), UV_RUN_DEFAULT); 104 MAKE_VALGRIND_HAPPY(); 105 return 0; 106 } 107 108 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(); 117 return 0; 118 } 119 120 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(); 128 return 0; 129 } 130 131 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(); 140 return 0; 141 } 142 143 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(); 152 return 0; 153 } 154 155 156 static void prepare_cb(uv_prepare_t* h) { 157 ASSERT_NOT_NULL(h); 158 uv_unref((uv_handle_t*)h); 159 } 160 161 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(); 169 return 0; 170 } 171 172 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(); 180 return 0; 181 } 182 183 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(); 192 return 0; 193 } 194 195 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(); 207 return 0; 208 } 209 210 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(); 219 return 0; 220 } 221 222 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(); 230 return 0; 231 } 232 233 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(); 242 return 0; 243 } 244 245 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(close_cb_called == 1); 254 MAKE_VALGRIND_HAPPY(); 255 return 0; 256 } 257 258 259 TEST_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 278 TEST_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 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(); 305 return 0; 306 } 307 308 309 TEST_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 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(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 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(); 355 return 0; 356 } 357 358 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(); 367 return 0; 368 } 369 370 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(connect_cb_called == 1); 378 ASSERT(shutdown_cb_called == 1); 379 do_close(&h); 380 MAKE_VALGRIND_HAPPY(); 381 return 0; 382 } 383 384 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(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 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(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 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(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