Skip to content

Commit 6932875

Browse files
authored
wasip3: Mask events reported through poll (#795)
Events such as a TCP connect will report that the socket is writable, but if the original `poll` call didn't request to get notified of that event then it shouldn't be reported.
1 parent 614ec67 commit 6932875

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

libc-bottom-half/cloudlibc/src/libc/poll/poll.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ int __wasilibc_poll_add(poll_state_t *state, uint32_t waitable,
317317
}
318318

319319
void __wasilibc_poll_ready(poll_state_t *state, short events) {
320+
events = events & state->pollfd->events;
320321
if (events != 0) {
321322
if (state->pollfd->revents == 0) {
322323
++state->event_count;

test/src/sockets-nonblocking.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,64 @@ void test_tcp_client() {
156156
TEST(close(server_socket_fd) == 0);
157157
}
158158

159+
static void test_poll_events() {
160+
int listener_fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
161+
162+
struct sockaddr_in server_address;
163+
socklen_t server_address_len = sizeof(server_address);
164+
server_address.sin_family = AF_INET;
165+
server_address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
166+
server_address.sin_port = 0;
167+
TEST(bind(listener_fd, (struct sockaddr *)&server_address,
168+
sizeof(server_address)) != -1);
169+
TEST(getsockname(listener_fd, (struct sockaddr *)&server_address,
170+
&server_address_len) != -1);
171+
TEST(listen(listener_fd, 1) != -1);
172+
173+
int client_fd;
174+
TEST((client_fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0)) != -1);
175+
TEST(connect(client_fd, (struct sockaddr *)&server_address,
176+
server_address_len) != -1 ||
177+
errno == EINPROGRESS);
178+
179+
struct pollfd pfds[3];
180+
pfds[0].fd = listener_fd;
181+
pfds[0].events = POLLRDNORM;
182+
pfds[0].revents = 0;
183+
pfds[1].fd = client_fd;
184+
pfds[1].events = POLLRDNORM;
185+
pfds[1].revents = 0;
186+
187+
while (!(pfds[0].revents & POLLRDNORM)) {
188+
TEST(poll(pfds, 2, -1) != -1);
189+
TEST(pfds[1].revents == 0);
190+
}
191+
TEST(pfds[0].revents == POLLRDNORM);
192+
193+
int server_fd;
194+
struct pollfd pfd;
195+
TEST((server_fd = accept4(listener_fd, NULL, NULL, SOCK_NONBLOCK)) != -1);
196+
pfd.fd = server_fd;
197+
pfd.events = POLLWRNORM;
198+
pfd.revents = 0;
199+
while (!(pfd.revents & POLLWRNORM))
200+
TEST(poll(&pfd, 1, -1) != -1);
201+
TEST(write(server_fd, "x", 1) == 1);
202+
TEST(close(server_fd) == 0);
203+
204+
while (!(pfds[1].revents & POLLRDNORM)) {
205+
TEST(poll(pfds, 2, -1) != -1);
206+
TEST(pfds[0].revents == 0);
207+
}
208+
TEST(pfds[1].revents == POLLRDNORM);
209+
210+
TEST(close(client_fd) == 0);
211+
TEST(close(listener_fd) == 0);
212+
}
213+
159214
int main(void) {
160215
test_tcp_client();
216+
test_poll_events();
161217

162218
return t_status;
163219
}

0 commit comments

Comments
 (0)