libuv-svace-build
111 строк · 3.4 Кб
1/* Copyright libuv project 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#ifdef _WIN3226
27TEST_IMPL(iouring_pollhup) {28RETURN_SKIP("Not on Windows.");29}
30
31#else /* !_WIN32 */32
33#include <unistd.h> /* close() */34
35static uv_pipe_t p1;36static uv_pipe_t p2;37static uv_idle_t idle_handle;38static int iters;39static int duped_fd;40static int newpipefds[2];41
42static void alloc_buffer(uv_handle_t* handle,43size_t suggested_size,44uv_buf_t* buf) {45static char slab[32];46*buf = uv_buf_init(slab, sizeof(slab));47}
48
49static void read_data2(uv_stream_t* stream,50ssize_t nread,51const uv_buf_t* buf) {52if (nread < 0) {53ASSERT_EQ(nread, UV_EOF);54ASSERT_OK(close(duped_fd));55duped_fd = -1;56uv_close((uv_handle_t*) &p2, NULL);57uv_close((uv_handle_t*) &idle_handle, NULL);58} else {59/* If nread == 0 is because of POLLHUP received still from pipefds[0] file60* description which is still referenced in duped_fd. It should not happen
61* if close(p1) was called after EPOLL_CTL_DEL.
62*/
63ASSERT_GT(nread, 0);64}65}
66
67static void idle_cb(uv_idle_t* handle) {68if (++iters == 1) {69ASSERT_OK(uv_pipe_open(&p2, newpipefds[0]));70ASSERT_OK(uv_read_start((uv_stream_t*) &p2, alloc_buffer, read_data2));71} else {72ASSERT_OK(uv_idle_stop(handle));73ASSERT_OK(close(newpipefds[1]));74newpipefds[1] = -1;75}76}
77
78static void read_data(uv_stream_t* stream,79ssize_t nread,80const uv_buf_t* buf) {81ASSERT_EQ(nread, UV_EOF);82uv_close((uv_handle_t*) stream, NULL);83ASSERT_OK(uv_idle_start(&idle_handle, idle_cb));84}
85
86TEST_IMPL(iouring_pollhup) {87uv_loop_t* loop;88int pipefds[2];89
90loop = uv_default_loop();91ASSERT_OK(uv_pipe_init(loop, &p1, 0));92ASSERT_OK(uv_pipe_init(loop, &p2, 0));93ASSERT_OK(uv_idle_init(loop, &idle_handle));94ASSERT_OK(pipe(pipefds));95ASSERT_OK(pipe(newpipefds));96
97ASSERT_OK(uv_pipe_open(&p1, pipefds[0]));98duped_fd = dup(pipefds[0]);99ASSERT_NE(duped_fd, -1);100
101ASSERT_OK(uv_read_start((uv_stream_t*) &p1, alloc_buffer, read_data));102ASSERT_OK(close(pipefds[1])); /* Close write end, generate POLLHUP. */103pipefds[1] = -1;104
105ASSERT_OK(uv_run(loop, UV_RUN_DEFAULT));106
107MAKE_VALGRIND_HAPPY(uv_default_loop());108return 0;109}
110
111#endif /* !_WIN32 */112