summaryrefslogtreecommitdiff
path: root/src/Action.cc
diff options
context:
space:
mode:
authorRichard Kettlewell <rjk@greenend.org.uk>2016-03-14 19:46:08 +0000
committerRichard Kettlewell <rjk@greenend.org.uk>2017-04-17 12:02:36 +0100
commitaada6ed8d00072c9ede1da3ba54cc32b7f6369e2 (patch)
treec1e135660036e13a1dcf02f875fd07aa35be68d4 /src/Action.cc
parent4f7d660daea26d519f5790ac7c5527634bdfe68e (diff)
Refactor Action ordering
Diffstat (limited to 'src/Action.cc')
-rw-r--r--src/Action.cc70
1 files changed, 44 insertions, 26 deletions
diff --git a/src/Action.cc b/src/Action.cc
index d2fed00..1f808e7 100644
--- a/src/Action.cc
+++ b/src/Action.cc
@@ -44,33 +44,12 @@ void ActionList::trigger() {
Action *a = it.second;
if(a->running)
continue;
- bool blocked = false;
- for(auto &p: a->predecessors) {
- if(actions.find(p.name) != actions.end()) {
- D("action %s blocked by dependency %s",
- a->name.c_str(), p.name.c_str());
- blocked = true;
- break;
- } else {
- auto d = status.find(p.name);
- if(d == status.end())
- throw std::logic_error(a->name + " follows unknown action " + p.name);
- if(p.succeeded && !d->second) {
- D("action %s depends on success of failed action %s",
- a->name.c_str(), p.name.c_str());
- cleanup(a, false, false);
- return trigger();
- }
- }
+ if(failed_by_dependency(a)) {
+ cleanup(a, false, false);
+ return trigger();
}
- for(auto &r: a->resources)
- if(contains(resources, r)) {
- D("action %s blocked by resource %s",
- a->name.c_str(), r.c_str());
- blocked = true;
- break;
- }
- if(blocked)
+ if(blocked_by_resource(a)
+ || blocked_by_dependency(a))
continue;
a->running = true;
for(std::string &r: a->resources)
@@ -107,3 +86,42 @@ void ActionList::cleanup(Action *a, bool succeeded, bool ran) {
}
throw std::logic_error("ActionList::cleanup");
}
+
+bool ActionList::blocked_by_resource(const Action *a) {
+ for(auto &r: a->resources)
+ if(contains(resources, r)) {
+ D("action %s blocked by resource %s",
+ a->name.c_str(), r.c_str());
+ return true;
+ }
+ return false;
+}
+
+bool ActionList::failed_by_dependency(const Action *a) {
+ for(auto &p: a->predecessors) {
+ auto d = status.find(p.name);
+ if(d != status.end() // P completed or failed
+ && p.succeeded // A needs P to have succeeded
+ && !d->second) { // P failed
+ D("action %s depends on success of failed action %s",
+ a->name.c_str(), p.name.c_str());
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ActionList::blocked_by_dependency(const Action *a) {
+ for(auto &p: a->predecessors) {
+ if(actions.find(p.name) != actions.end()) {
+ D("action %s blocked by dependency %s",
+ a->name.c_str(), p.name.c_str());
+ return true;
+ } else { // Sanity check
+ auto d = status.find(p.name);
+ if(d == status.end())
+ throw std::logic_error(a->name + " follows unknown action " + p.name);
+ }
+ }
+ return false;
+}