Mercurial
comparison third_party/libuv/test/test-poll-oob.c @ 160:948de3f54cea
[ThirdParty] Added libuv
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Wed, 14 Jan 2026 19:39:52 -0800 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 159:05cf9467a1c3 | 160:948de3f54cea |
|---|---|
| 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 #if !defined(_WIN32) | |
| 23 | |
| 24 #include "uv.h" | |
| 25 #include "task.h" | |
| 26 | |
| 27 #include <errno.h> | |
| 28 #include <sys/socket.h> | |
| 29 #include <sys/ioctl.h> | |
| 30 #include <unistd.h> | |
| 31 #include <string.h> | |
| 32 | |
| 33 static uv_tcp_t server_handle; | |
| 34 static uv_tcp_t client_handle; | |
| 35 static uv_tcp_t peer_handle; | |
| 36 static uv_poll_t poll_req[2]; | |
| 37 static uv_idle_t idle; | |
| 38 static uv_os_fd_t client_fd; | |
| 39 static uv_os_fd_t server_fd; | |
| 40 static int ticks; | |
| 41 static const int kMaxTicks = 10; | |
| 42 static int cli_pr_check = 0; | |
| 43 static int cli_rd_check = 0; | |
| 44 static int srv_rd_check = 0; | |
| 45 | |
| 46 static int got_eagain(void) { | |
| 47 return errno == EAGAIN | |
| 48 || errno == EINPROGRESS | |
| 49 #ifdef EWOULDBLOCK | |
| 50 || errno == EWOULDBLOCK | |
| 51 #endif | |
| 52 ; | |
| 53 } | |
| 54 | |
| 55 static void idle_cb(uv_idle_t* idle) { | |
| 56 uv_sleep(100); | |
| 57 if (++ticks < kMaxTicks) | |
| 58 return; | |
| 59 | |
| 60 uv_poll_stop(&poll_req[0]); | |
| 61 uv_poll_stop(&poll_req[1]); | |
| 62 uv_close((uv_handle_t*) &server_handle, NULL); | |
| 63 uv_close((uv_handle_t*) &client_handle, NULL); | |
| 64 uv_close((uv_handle_t*) &peer_handle, NULL); | |
| 65 uv_close((uv_handle_t*) idle, NULL); | |
| 66 } | |
| 67 | |
| 68 static void poll_cb(uv_poll_t* handle, int status, int events) { | |
| 69 char buffer[5]; | |
| 70 int n; | |
| 71 int fd; | |
| 72 | |
| 73 ASSERT_OK(uv_fileno((uv_handle_t*)handle, &fd)); | |
| 74 memset(buffer, 0, 5); | |
| 75 | |
| 76 if (events & UV_PRIORITIZED) { | |
| 77 do | |
| 78 n = recv(client_fd, &buffer, 5, MSG_OOB); | |
| 79 while (n == -1 && errno == EINTR); | |
| 80 ASSERT(n >= 0 || errno != EINVAL); | |
| 81 cli_pr_check = 1; | |
| 82 ASSERT_OK(uv_poll_stop(&poll_req[0])); | |
| 83 ASSERT_OK(uv_poll_start(&poll_req[0], | |
| 84 UV_READABLE | UV_WRITABLE, | |
| 85 poll_cb)); | |
| 86 } | |
| 87 if (events & UV_READABLE) { | |
| 88 if (fd == client_fd) { | |
| 89 do | |
| 90 n = recv(client_fd, &buffer, 5, 0); | |
| 91 while (n == -1 && errno == EINTR); | |
| 92 ASSERT(n >= 0 || errno != EINVAL); | |
| 93 if (cli_rd_check == 1) { | |
| 94 ASSERT_OK(strncmp(buffer, "world", n)); | |
| 95 ASSERT_EQ(5, n); | |
| 96 cli_rd_check = 2; | |
| 97 } | |
| 98 if (cli_rd_check == 0) { | |
| 99 ASSERT_EQ(4, n); | |
| 100 ASSERT_OK(strncmp(buffer, "hello", n)); | |
| 101 cli_rd_check = 1; | |
| 102 do { | |
| 103 do | |
| 104 n = recv(server_fd, &buffer, 5, 0); | |
| 105 while (n == -1 && errno == EINTR); | |
| 106 if (n > 0) { | |
| 107 ASSERT_EQ(5, n); | |
| 108 ASSERT_OK(strncmp(buffer, "world", n)); | |
| 109 cli_rd_check = 2; | |
| 110 } | |
| 111 } while (n > 0); | |
| 112 | |
| 113 ASSERT(got_eagain()); | |
| 114 } | |
| 115 } | |
| 116 if (fd == server_fd) { | |
| 117 do | |
| 118 n = recv(server_fd, &buffer, 3, 0); | |
| 119 while (n == -1 && errno == EINTR); | |
| 120 ASSERT(n >= 0 || errno != EINVAL); | |
| 121 ASSERT_EQ(3, n); | |
| 122 ASSERT_OK(strncmp(buffer, "foo", n)); | |
| 123 srv_rd_check = 1; | |
| 124 uv_poll_stop(&poll_req[1]); | |
| 125 } | |
| 126 } | |
| 127 if (events & UV_WRITABLE) { | |
| 128 do { | |
| 129 n = send(client_fd, "foo", 3, 0); | |
| 130 } while (n < 0 && errno == EINTR); | |
| 131 ASSERT_EQ(3, n); | |
| 132 } | |
| 133 } | |
| 134 | |
| 135 static void connection_cb(uv_stream_t* handle, int status) { | |
| 136 int r; | |
| 137 | |
| 138 ASSERT_OK(status); | |
| 139 ASSERT_OK(uv_accept(handle, (uv_stream_t*) &peer_handle)); | |
| 140 ASSERT_OK(uv_fileno((uv_handle_t*) &peer_handle, &server_fd)); | |
| 141 ASSERT_OK(uv_poll_init_socket(uv_default_loop(), | |
| 142 &poll_req[0], | |
| 143 client_fd)); | |
| 144 ASSERT_OK(uv_poll_init_socket(uv_default_loop(), | |
| 145 &poll_req[1], | |
| 146 server_fd)); | |
| 147 ASSERT_OK(uv_poll_start(&poll_req[0], | |
| 148 UV_PRIORITIZED | UV_READABLE | UV_WRITABLE, | |
| 149 poll_cb)); | |
| 150 ASSERT_OK(uv_poll_start(&poll_req[1], | |
| 151 UV_READABLE, | |
| 152 poll_cb)); | |
| 153 do { | |
| 154 r = send(server_fd, "hello", 5, MSG_OOB); | |
| 155 } while (r < 0 && errno == EINTR); | |
| 156 ASSERT_EQ(5, r); | |
| 157 | |
| 158 do { | |
| 159 r = send(server_fd, "world", 5, 0); | |
| 160 } while (r < 0 && errno == EINTR); | |
| 161 ASSERT_EQ(5, r); | |
| 162 | |
| 163 ASSERT_OK(uv_idle_start(&idle, idle_cb)); | |
| 164 } | |
| 165 | |
| 166 | |
| 167 TEST_IMPL(poll_oob) { | |
| 168 struct sockaddr_in addr; | |
| 169 int r = 0; | |
| 170 uv_loop_t* loop; | |
| 171 | |
| 172 ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); | |
| 173 loop = uv_default_loop(); | |
| 174 | |
| 175 ASSERT_OK(uv_tcp_init(loop, &server_handle)); | |
| 176 ASSERT_OK(uv_tcp_init(loop, &client_handle)); | |
| 177 ASSERT_OK(uv_tcp_init(loop, &peer_handle)); | |
| 178 ASSERT_OK(uv_idle_init(loop, &idle)); | |
| 179 ASSERT_OK(uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr, 0)); | |
| 180 ASSERT_OK(uv_listen((uv_stream_t*) &server_handle, 1, connection_cb)); | |
| 181 | |
| 182 /* Ensure two separate packets */ | |
| 183 ASSERT_OK(uv_tcp_nodelay(&client_handle, 1)); | |
| 184 | |
| 185 client_fd = socket(PF_INET, SOCK_STREAM, 0); | |
| 186 ASSERT_GE(client_fd, 0); | |
| 187 do { | |
| 188 errno = 0; | |
| 189 r = connect(client_fd, (const struct sockaddr*)&addr, sizeof(addr)); | |
| 190 } while (r == -1 && errno == EINTR); | |
| 191 ASSERT_OK(r); | |
| 192 | |
| 193 ASSERT_OK(uv_run(loop, UV_RUN_DEFAULT)); | |
| 194 | |
| 195 ASSERT_EQ(ticks, kMaxTicks); | |
| 196 | |
| 197 /* Did client receive the POLLPRI message */ | |
| 198 ASSERT_EQ(1, cli_pr_check); | |
| 199 /* Did client receive the POLLIN message */ | |
| 200 ASSERT_EQ(2, cli_rd_check); | |
| 201 /* Could we write with POLLOUT and did the server receive our POLLOUT message | |
| 202 * through POLLIN. | |
| 203 */ | |
| 204 ASSERT_EQ(1, srv_rd_check); | |
| 205 | |
| 206 MAKE_VALGRIND_HAPPY(loop); | |
| 207 return 0; | |
| 208 } | |
| 209 | |
| 210 #else | |
| 211 | |
| 212 typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ | |
| 213 | |
| 214 #endif |