forked from lix-project/lix
MonitorFdHup: Make it work on macOS again
It appears that on current macOS versions, our use of poll() to detect client disconnects no longer works. As a workaround, poll() for POLLRDNORM, since this *will* wake up when the client has disconnected. The downside is that it also wakes up when input is available. So just sleep for a bit in that case. This means that on macOS, a client disconnect may take up to a second to be detected, but that's better than not being detected at all. Fixes #7584.
This commit is contained in:
parent
6dd8b3b412
commit
9fc8d00d74
|
@ -22,27 +22,38 @@ public:
|
||||||
{
|
{
|
||||||
thread = std::thread([fd]() {
|
thread = std::thread([fd]() {
|
||||||
while (true) {
|
while (true) {
|
||||||
/* Wait indefinitely until a POLLHUP occurs. */
|
/* Wait indefinitely until a POLLHUP occurs. */
|
||||||
struct pollfd fds[1];
|
struct pollfd fds[1];
|
||||||
fds[0].fd = fd;
|
fds[0].fd = fd;
|
||||||
/* This shouldn't be necessary, but macOS doesn't seem to
|
/* Polling for no specific events (i.e. just waiting
|
||||||
like a zeroed out events field.
|
for an error/hangup) doesn't work on macOS
|
||||||
See rdar://37537852.
|
anymore. So wait for read events and ignore
|
||||||
*/
|
them. */
|
||||||
fds[0].events = POLLHUP;
|
fds[0].events =
|
||||||
auto count = poll(fds, 1, -1);
|
#ifdef __APPLE__
|
||||||
if (count == -1) abort(); // can't happen
|
POLLRDNORM
|
||||||
/* This shouldn't happen, but can on macOS due to a bug.
|
#else
|
||||||
See rdar://37550628.
|
0
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
auto count = poll(fds, 1, -1);
|
||||||
|
if (count == -1) abort(); // can't happen
|
||||||
|
/* This shouldn't happen, but can on macOS due to a bug.
|
||||||
|
See rdar://37550628.
|
||||||
|
|
||||||
This may eventually need a delay or further
|
This may eventually need a delay or further
|
||||||
coordination with the main thread if spinning proves
|
coordination with the main thread if spinning proves
|
||||||
too harmful.
|
too harmful.
|
||||||
*/
|
*/
|
||||||
if (count == 0) continue;
|
if (count == 0) continue;
|
||||||
assert(fds[0].revents & POLLHUP);
|
if (fds[0].revents & POLLHUP) {
|
||||||
triggerInterrupt();
|
triggerInterrupt();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
/* This will only happen on macOS. We sleep a bit to
|
||||||
|
avoid waking up too often if the client is sending
|
||||||
|
input. */
|
||||||
|
sleep(1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue