wip for console pool on windows
authorNico Weber <thakis@chromium.org>
Tue, 13 May 2014 19:35:52 +0000 (12:35 -0700)
committerNico Weber <thakis@chromium.org>
Tue, 13 May 2014 19:37:31 +0000 (12:37 -0700)
doc/manual.asciidoc
src/manifest_parser.cc
src/subprocess-posix.cc
src/subprocess-win32.cc
src/subprocess.h

index 5b0c1fe..18760dd 100644 (file)
@@ -664,8 +664,6 @@ While a task in the `console` pool is running, Ninja's regular output (such
 as progress status and output from concurrent tasks) is buffered until
 it completes.
 
-This feature is not yet available on Windows.
-
 Ninja file reference
 --------------------
 
index a566eda..6fa4f7c 100644 (file)
@@ -317,10 +317,6 @@ bool ManifestParser::ParseEdge(string* err) {
     Pool* pool = state_->LookupPool(pool_name);
     if (pool == NULL)
       return lexer_.Error("unknown pool name '" + pool_name + "'", err);
-#ifdef _WIN32
-    if (pool == &State::kConsolePool)
-      return lexer_.Error("console pool unsupported on Windows", err);
-#endif
     edge->pool_ = pool;
   }
 
index 793d48f..7311f64 100644 (file)
@@ -84,6 +84,8 @@ bool Subprocess::Start(SubprocessSet* set, const string& command) {
         error_pipe = 2;
         close(output_pipe[1]);
       }
+      // In the console case, child_pipe is still inherited by the child and
+      // closed when the subprocess finishes, which then notifies ninja.
 
       execl("/bin/sh", "/bin/sh", "-c", command.c_str(), (char *) NULL);
     } while (false);
index c9607e1..c71f95b 100644 (file)
@@ -21,7 +21,9 @@
 
 #include "util.h"
 
-Subprocess::Subprocess() : child_(NULL) , overlapped_(), is_reading_(false) {
+Subprocess::Subprocess(bool use_console) : child_(NULL) , overlapped_(),
+                                           is_reading_(false),
+                                           use_console_(use_console) {
 }
 
 Subprocess::~Subprocess() {
@@ -87,10 +89,14 @@ bool Subprocess::Start(SubprocessSet* set, const string& command) {
   STARTUPINFOA startup_info;
   memset(&startup_info, 0, sizeof(startup_info));
   startup_info.cb = sizeof(STARTUPINFO);
-  startup_info.dwFlags = STARTF_USESTDHANDLES;
-  startup_info.hStdInput = nul;
-  startup_info.hStdOutput = child_pipe;
-  startup_info.hStdError = child_pipe;
+  if (!use_console_) {
+    startup_info.dwFlags = STARTF_USESTDHANDLES;
+    startup_info.hStdInput = nul;
+    startup_info.hStdOutput = child_pipe;
+    startup_info.hStdError = child_pipe;
+  }
+  // In the console case, child_pipe is still inherited by the child and closed
+  // when the subprocess finishes, which then notifies ninja.
 
   PROCESS_INFORMATION process_info;
   memset(&process_info, 0, sizeof(process_info));
@@ -215,9 +221,7 @@ BOOL WINAPI SubprocessSet::NotifyInterrupted(DWORD dwCtrlType) {
 }
 
 Subprocess *SubprocessSet::Add(const string& command, bool use_console) {
-  assert(!use_console); // We don't support this yet on Windows.
-
-  Subprocess *subprocess = new Subprocess;
+  Subprocess *subprocess = new Subprocess(use_console);
   if (!subprocess->Start(this, command)) {
     delete subprocess;
     return 0;
@@ -269,7 +273,9 @@ Subprocess* SubprocessSet::NextFinished() {
 void SubprocessSet::Clear() {
   for (vector<Subprocess*>::iterator i = running_.begin();
        i != running_.end(); ++i) {
-    if ((*i)->child_) {
+    // Since the foreground process is in our process group, it will receive a
+    // SIGINT at the same time as us.  XXX is this true on windows?
+    if ((*i)->child_ && !(*i)->use_console_) {
       if (!GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,
                                     GetProcessId((*i)->child_))) {
         Win32Fatal("GenerateConsoleCtrlEvent");
index 6ea6f62..b7a1a4c 100644 (file)
@@ -44,14 +44,13 @@ struct Subprocess {
   const string& GetOutput() const;
 
  private:
+  Subprocess(bool use_console);
   bool Start(struct SubprocessSet* set, const string& command);
   void OnPipeReady();
 
   string buf_;
 
 #ifdef _WIN32
-  Subprocess();
-
   /// Set up pipe_ as the parent-side pipe of the subprocess; return the
   /// other end of the pipe, usable in the child process.
   HANDLE SetupPipe(HANDLE ioport);
@@ -62,8 +61,6 @@ struct Subprocess {
   char overlapped_buf_[4 << 10];
   bool is_reading_;
 #else
-  Subprocess(bool use_console);
-
   int fd_;
   pid_t pid_;
 #endif