Check pending SIGINT after ppoll/pselect
authorTaiju Tsuiki <tzik@google.com>
Fri, 9 Jan 2015 22:19:11 +0000 (07:19 +0900)
committertzik <tzik@google.com>
Mon, 19 Jan 2015 00:55:51 +0000 (09:55 +0900)
ppoll/pselect prioritizes file descriptor events over
a signal delivery. So a flood of events prevents ninja
from reacting keyboard interruption by the user.

This CL adds a check for pending keyboard interruptions after
file descriptor events.

src/subprocess-posix.cc

index 743e406..40c9ae1 100644 (file)
 
 #include "util.h"
 
+namespace {
+
+bool HasPendingInterruption() {
+  sigset_t pending;
+  sigemptyset(&pending);
+  if (sigpending(&pending) == -1) {
+    perror("ninja: sigpending");
+    return false;
+  }
+  return sigismember(&pending, SIGINT);
+}
+
+}  // anonymous namespace
+
 Subprocess::Subprocess(bool use_console) : fd_(-1), pid_(-1),
                                            use_console_(use_console) {
 }
+
 Subprocess::~Subprocess() {
   if (fd_ >= 0)
     close(fd_);
@@ -209,6 +224,9 @@ bool SubprocessSet::DoWork() {
     return interrupted_;
   }
 
+  if (HasPendingInterruption())
+    return true;
+
   nfds_t cur_nfd = 0;
   for (vector<Subprocess*>::iterator i = running_.begin();
        i != running_.end(); ) {
@@ -256,6 +274,9 @@ bool SubprocessSet::DoWork() {
     return interrupted_;
   }
 
+  if (HasPendingInterruption())
+    return true;
+
   for (vector<Subprocess*>::iterator i = running_.begin();
        i != running_.end(); ) {
     int fd = (*i)->fd_;