diff options
author | Evan Martin <martine@danga.com> | 2010-11-29 04:12:59 (GMT) |
---|---|---|
committer | Evan Martin <martine@danga.com> | 2010-11-29 04:12:59 (GMT) |
commit | d4c02f6ff58da0bd134f59ab5cac711999222602 (patch) | |
tree | 60b1514d496043566a4e3a879577e42dcf4df430 | |
parent | 63ca311423b94ce2094f9cc7dc9ffe38a4757aee (diff) | |
download | Ninja-d4c02f6ff58da0bd134f59ab5cac711999222602.zip Ninja-d4c02f6ff58da0bd134f59ab5cac711999222602.tar.gz Ninja-d4c02f6ff58da0bd134f59ab5cac711999222602.tar.bz2 |
use async runner serially
-rw-r--r-- | build.cc | 46 | ||||
-rw-r--r-- | subprocess.cc | 7 | ||||
-rw-r--r-- | subprocess.h | 2 |
3 files changed, 39 insertions, 16 deletions
@@ -3,6 +3,7 @@ #include <stdio.h> #include "ninja.h" +#include "subprocess.h" bool Plan::AddTarget(Node* node, string* err) { Edge* edge = node->in_edge_; @@ -89,32 +90,47 @@ struct RealCommandRunner : public CommandRunner { virtual void WaitForCommands(string* err); virtual Edge* NextFinishedCommand(); - queue<Edge*> finished_; + SubprocessSet subprocs_; + map<Subprocess*, Edge*> subproc_to_edge_; }; bool RealCommandRunner::StartCommand(Edge* edge) { string err; string command = edge->EvaluateCommand(); printf(" %s\n", command.c_str()); - int ret = system(command.c_str()); - finished_.push(edge); - if (WIFEXITED(ret)) { - int exit = WEXITSTATUS(ret); - if (exit == 0) - return true; - err = "nonzero exit status"; - } else { - err = "something else went wrong"; - } - return false; + Subprocess* subproc = new Subprocess; + subproc_to_edge_.insert(make_pair(subproc, edge)); + if (!subproc->Start(command, &err)) + return false; + + subprocs_.Add(subproc); + return true; } + void RealCommandRunner::WaitForCommands(string* err) { + while (subprocs_.finished_.empty()) { + subprocs_.DoWork(err); // XXX handle err + } } + Edge* RealCommandRunner::NextFinishedCommand() { - if (finished_.empty()) + Subprocess* subproc = subprocs_.NextFinished(); + if (!subproc) return NULL; - Edge* edge = finished_.front(); - finished_.pop(); + + if (!subproc->stdout_.buf_.empty()) { + printf("%d> %s\n", subproc->pid_, subproc->stdout_.buf_.c_str()); + } + if (!subproc->stderr_.buf_.empty()) { + printf("E%d> %s\n", subproc->pid_, subproc->stderr_.buf_.c_str()); + } + + map<Subprocess*, Edge*>::iterator i = subproc_to_edge_.find(subproc); + Edge* edge = i->second; + subproc_to_edge_.erase(i); + + delete subproc; + // XXX extract exit code, etc. return edge; } diff --git a/subprocess.cc b/subprocess.cc index 82d3683..0c93c4a 100644 --- a/subprocess.cc +++ b/subprocess.cc @@ -146,3 +146,10 @@ void SubprocessSet::DoWork(string* err) { } } +Subprocess* SubprocessSet::NextFinished() { + if (finished_.empty()) + return NULL; + Subprocess* subproc = finished_.front(); + finished_.pop(); + return subproc; +} diff --git a/subprocess.h b/subprocess.h index 234d255..91f0771 100644 --- a/subprocess.h +++ b/subprocess.h @@ -35,8 +35,8 @@ struct Subprocess { struct SubprocessSet { void Add(Subprocess* subprocess); void DoWork(string* err); + Subprocess* NextFinished(); - int max_running_; vector<Subprocess*> running_; queue<Subprocess*> finished_; }; |