From 37a2496f7f26d4493971dbf593adf4f5c3c76472 Mon Sep 17 00:00:00 2001 From: Rachel Heaton Date: Tue, 23 Nov 2021 07:03:29 -0800 Subject: [PATCH] Handle return events for poll() (#836) On MacOS, there was a situation where poll() had POLLHUP in revents, which was not being handled by WaitForEvent. This caused poll to continuously run, taking CPU time (up to 100%). In spite of requesting POLLERR | POLLIN or POLLERR | POLLOUT, poll will also potentially return POLLHUP and POLLNVAL. [From the opengroup poll spec:](https://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html) "In addition, poll() shall set the POLLHUP, POLLERR, and POLLNVAL flag in revents if the condition is true, even if the application did not set the corresponding bit in events." We've removed the request for POLLERR from the file descriptor as it is unnecessary and misleading. This fix addresses the CPU usage on MacOS 11.6 when running a monitor that cannot connect to its nodes. Co-authored-by: Jacob Champion --- src/monitor/health_check_worker.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/monitor/health_check_worker.c b/src/monitor/health_check_worker.c index 21e0840ee..dd6e0a39c 100644 --- a/src/monitor/health_check_worker.c +++ b/src/monitor/health_check_worker.c @@ -748,11 +748,11 @@ WaitForEvent(List *healthCheckList) if (healthCheck->pollingStatus == PGRES_POLLING_READING) { - pollEventMask = POLLERR | POLLIN; + pollEventMask = POLLIN; } else if (healthCheck->pollingStatus == PGRES_POLLING_WRITING) { - pollEventMask = POLLERR | POLLOUT; + pollEventMask = POLLOUT; } pollFileDescriptor->fd = PQsocket(connection); @@ -786,8 +786,7 @@ WaitForEvent(List *healthCheckList) HealthCheck *healthCheck = (HealthCheck *) lfirst(healthCheckCell); struct pollfd *pollFileDescriptor = &pollFDs[healthCheckIndex]; - healthCheck->readyToPoll = pollFileDescriptor->revents & - pollFileDescriptor->events; + healthCheck->readyToPoll = pollFileDescriptor->revents != 0; healthCheckIndex++; }