about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2018-02-15T10·43+0100
committerGitHub <noreply@github.com>2018-02-15T10·43+0100
commitd26b71fda61196033c27cbac0ffed2a94fd1fe4c (patch)
tree1608d000ef10c094622cb9ba5c9aec639cd161ce
parent96d48318cb838cb67916e443266210c46fe4bf87 (diff)
parentac973a6d3c0ff2f505dece8e9f1508c6f77553a5 (diff)
Merge pull request #1872 from shlevy/macOS-poll-fix
monitor-fds: Fix on macOS.
-rw-r--r--src/libutil/monitor-fd.hh30
1 files changed, 23 insertions, 7 deletions
diff --git a/src/libutil/monitor-fd.hh b/src/libutil/monitor-fd.hh
index e0ec66c01803..5ee0b88ef50f 100644
--- a/src/libutil/monitor-fd.hh
+++ b/src/libutil/monitor-fd.hh
@@ -21,13 +21,29 @@ public:
     MonitorFdHup(int fd)
     {
         thread = std::thread([fd]() {
-            /* Wait indefinitely until a POLLHUP occurs. */
-            struct pollfd fds[1];
-            fds[0].fd = fd;
-            fds[0].events = 0;
-            if (poll(fds, 1, -1) == -1) abort(); // can't happen
-            assert(fds[0].revents & POLLHUP);
-            triggerInterrupt();
+            while (true) {
+              /* Wait indefinitely until a POLLHUP occurs. */
+              struct pollfd fds[1];
+              fds[0].fd = fd;
+              /* This shouldn't be necessary, but macOS doesn't seem to
+                 like a zeroed out events field.
+                 See rdar://37537852.
+              */
+              fds[0].events = POLLHUP;
+              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
+                 coordination with the main thread if spinning proves
+                 too harmful.
+               */
+              if (count == 0) continue;
+              assert(fds[0].revents & POLLHUP);
+              triggerInterrupt();
+              break;
+            }
         });
     };