1 /* Copyright (c) 2015, Ben Noordhuis <info@bnoordhuis.nl> 2 * 3 * Permission to use, copy, modify, and/or distribute this software for any 4 * purpose with or without fee is hereby granted, provided that the above 5 * copyright notice and this permission notice appear in all copies. 6 * 7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 */ 15 16 #include "uv.h" 17 #include "task.h" 18 19 #ifdef _WIN32 20 21 TEST_IMPL(pipe_set_non_blocking) { 22 RETURN_SKIP("Test not implemented on Windows."); 23 } 24 25 #else /* !_WIN32 */ 26 27 #include <errno.h> 28 #include <string.h> 29 #include <sys/socket.h> 30 #include <sys/types.h> 31 #include <sys/un.h> 32 #include <unistd.h> 33 34 struct thread_ctx { 35 uv_barrier_t barrier; 36 int fd; 37 }; 38 39 static void thread_main(void* arg) { 40 struct thread_ctx* ctx; 41 char buf[4096]; 42 ssize_t n; 43 44 ctx = arg; 45 uv_barrier_wait(&ctx->barrier); 46 47 do 48 n = read(ctx->fd, buf, sizeof(buf)); 49 while (n > 0 || (n == -1 && errno == EINTR)); 50 51 ASSERT(n == 0); 52 } 53 54 TEST_IMPL(pipe_set_non_blocking) { 55 struct thread_ctx ctx; 56 uv_pipe_t pipe_handle; 57 uv_thread_t thread; 58 size_t nwritten; 59 char data[4096]; 60 uv_buf_t buf; 61 int fd[2]; 62 int n; 63 64 ASSERT(0 == uv_pipe_init(uv_default_loop(), &pipe_handle, 0)); 65 ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, fd)); 66 ASSERT(0 == uv_pipe_open(&pipe_handle, fd[0])); 67 ASSERT(0 == uv_stream_set_blocking((uv_stream_t*) &pipe_handle, 1)); 68 69 ctx.fd = fd[1]; 70 ASSERT(0 == uv_barrier_init(&ctx.barrier, 2)); 71 ASSERT(0 == uv_thread_create(&thread, thread_main, &ctx)); 72 uv_barrier_wait(&ctx.barrier); 73 74 buf.len = sizeof(data); 75 buf.base = data; 76 memset(data, '.', sizeof(data)); 77 78 nwritten = 0; 79 while (nwritten < 10 << 20) { 80 /* The stream is in blocking mode so uv_try_write() should always succeed 81 * with the exact number of bytes that we wanted written. 82 */ 83 n = uv_try_write((uv_stream_t*) &pipe_handle, &buf, 1); 84 ASSERT(n == sizeof(data)); 85 nwritten += n; 86 } 87 88 uv_close((uv_handle_t*) &pipe_handle, NULL); 89 ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); 90 91 ASSERT(0 == uv_thread_join(&thread)); 92 ASSERT(0 == close(fd[1])); /* fd[0] is closed by uv_close(). */ 93 uv_barrier_destroy(&ctx.barrier); 94 95 MAKE_VALGRIND_HAPPY(); 96 return 0; 97 } 98 99 #endif /* !_WIN32 */ 100