From 04b33ef098f453d7c46c6b45990d4ceb36716620 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Thu, 5 May 2022 00:43:26 -0500 Subject: [PATCH] server: Don't poll for POLLIN or POLLPRI if there are alerted read asyncs. Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- dlls/ws2_32/tests/afd.c | 2 +- server/sock.c | 34 +++++++++++++++++++++------------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/dlls/ws2_32/tests/afd.c b/dlls/ws2_32/tests/afd.c index cf27b4003c5..2ace83f5e21 100644 --- a/dlls/ws2_32/tests/afd.c +++ b/dlls/ws2_32/tests/afd.c @@ -382,7 +382,7 @@ static void test_poll(void) ok(size == 1, "got size %lu\n", size); ret = WaitForSingleObject(event, 0); - todo_wine ok(ret == WAIT_TIMEOUT, "got %#x\n", ret); + ok(ret == WAIT_TIMEOUT, "got %#x\n", ret); ret = send(client, "a", 1, 0); ok(ret == 1, "got %d\n", ret); diff --git a/server/sock.c b/server/sock.c index db0df5ecf79..cf25994c383 100644 --- a/server/sock.c +++ b/server/sock.c @@ -1229,6 +1229,18 @@ static int sock_get_poll_events( struct fd *fd ) if (!sock->type) /* not initialized yet */ return -1; + LIST_FOR_EACH_ENTRY( req, &poll_list, struct poll_req, entry ) + { + unsigned int i; + + for (i = 0; i < req->count; ++i) + { + if (req->sockets[i].sock != sock) continue; + + ev |= poll_flags_from_afd( sock, req->sockets[i].mask ); + } + } + switch (sock->state) { case SOCK_UNCONNECTED: @@ -1271,7 +1283,15 @@ static int sock_get_poll_events( struct fd *fd ) } else if (async_queued( &sock->read_q )) { - if (async_waiting( &sock->read_q )) ev |= POLLIN | POLLPRI; + /* Clear POLLIN and POLLPRI if we have an alerted async, even if + * we're polling this socket for READ or OOB. We can't signal the + * poll if the pending async will read all of the data [cf. the + * matching logic in sock_dispatch_asyncs()], but we also don't + * want to spin polling for POLLIN if we're not going to use it. */ + if (async_waiting( &sock->read_q )) + ev |= POLLIN | POLLPRI; + else + ev &= ~(POLLIN | POLLPRI); } else { @@ -1302,18 +1322,6 @@ static int sock_get_poll_events( struct fd *fd ) break; } - LIST_FOR_EACH_ENTRY( req, &poll_list, struct poll_req, entry ) - { - unsigned int i; - - for (i = 0; i < req->count; ++i) - { - if (req->sockets[i].sock != sock) continue; - - ev |= poll_flags_from_afd( sock, req->sockets[i].mask ); - } - } - return ev; }