summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Martin <martine@danga.com>2010-11-29 04:12:59 (GMT)
committerEvan Martin <martine@danga.com>2010-11-29 04:12:59 (GMT)
commitd4c02f6ff58da0bd134f59ab5cac711999222602 (patch)
tree60b1514d496043566a4e3a879577e42dcf4df430
parent63ca311423b94ce2094f9cc7dc9ffe38a4757aee (diff)
downloadNinja-d4c02f6ff58da0bd134f59ab5cac711999222602.zip
Ninja-d4c02f6ff58da0bd134f59ab5cac711999222602.tar.gz
Ninja-d4c02f6ff58da0bd134f59ab5cac711999222602.tar.bz2
use async runner serially
-rw-r--r--build.cc46
-rw-r--r--subprocess.cc7
-rw-r--r--subprocess.h2
3 files changed, 39 insertions, 16 deletions
diff --git a/build.cc b/build.cc
index 6f5c088..d2d9a8d 100644
--- a/build.cc
+++ b/build.cc
@@ -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_;
};