From c1d6c0690ec44375e65139d607f5c050665837e4 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sat, 23 Apr 2022 22:18:55 +0200 Subject: [PATCH] Fix poll() edge case on macOS, clean up logic Return from poll_for_request() when CrossThreadChannel is closed/destroyed. -- see also f4166fb61d2 This also cleans up poll API usage, and check for nonnegative return value is added. --- libs/pbd/crossthread.posix.cc | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/libs/pbd/crossthread.posix.cc b/libs/pbd/crossthread.posix.cc index 97625ce2aa..08db4debb2 100644 --- a/libs/pbd/crossthread.posix.cc +++ b/libs/pbd/crossthread.posix.cc @@ -1,6 +1,6 @@ /* * Copyright (C) 2014-2016 Paul Davis - * Copyright (C) 2015-2016 Robin Gareus + * Copyright (C) 2015-2022 Robin Gareus * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -95,21 +95,31 @@ CrossThreadChannel::deliver (char msg) bool CrossThreadChannel::poll_for_request() { - struct pollfd pfd[1]; - pfd[0].fd = fds[0]; - pfd[0].events = POLLIN|POLLERR|POLLHUP; + struct pollfd pfd; + pfd.fd = fds[0]; + pfd.events = POLLIN|POLLERR|POLLHUP|POLLNVAL; while(true) { - if (poll (pfd, 1, -1) < 0) { +#ifdef __APPLE__ + /* on macOS poll() will not return when the pipe + * is closed in an EOF state. ork around with a timeout. + */ + int rv = poll (&pfd, 1, 1000); +#else + int rv = poll (&pfd, 1, -1); +#endif + if (rv == -1) { + /* error */ if (errno == EINTR) { continue; } break; } - if (pfd[0].revents & ~POLLIN) { + + if (pfd.revents & ~POLLIN) { break; } - if (pfd[0].revents & POLLIN) { + if (rv > 0 && pfd.revents & POLLIN) { return true; } }