diff options
author | Philippe Coval <philippe.coval@osg.samsung.com> | 2017-08-27 15:10:01 +0200 |
---|---|---|
committer | Philippe Coval <philippe.coval@osg.samsung.com> | 2017-10-10 11:24:00 +0200 |
commit | be26e6e43be56e814af1372f203e1b2748eebb04 (patch) | |
tree | b81b6e7c13b6ea6c21277405b1cd21ec07c40f43 | |
parent | 81c02354dfd7634708eb79547e9448150cc016a6 (diff) | |
download | scons-sandbox/pcoval/on/master/review.tar.gz scons-sandbox/pcoval/on/master/review.tar.bz2 scons-sandbox/pcoval/on/master/review.zip |
Fix a pendning children and side effects bugsandbox/pcoval/on/master/review
Bug: http://scons.tigris.org/issues/show_bug.cgi?id=2777O
Change-Id: Iafa328a0430c675d52cdba50e6984e4c3e74e29e
Credit-to: Emil Stanchev <estanchev@tigris.org>
Origin: http://scons.tigris.org/nonav/issues/showattachment.cgi/894/Fix-a-pending-children-and-side-effects-bug_v3.patch
-rw-r--r-- | src/engine/SCons/Taskmaster.py | 21 | ||||
-rw-r--r-- | src/engine/SCons/TaskmasterTests.py | 32 |
2 files changed, 52 insertions, 1 deletions
diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 17507a6f..b77c375a 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -1016,6 +1016,27 @@ class Taskmaster(object): to_visit = to_visit | parents pending_children = pending_children - parents + # Clean up the other branches of side effect + for se in node.get_side_effects(): + waiting_s_e = se.get_waiting_s_e() + pending_children = pending_children - waiting_s_e + stack = set(waiting_s_e) + if T: + for n in waiting_s_e: + T.write(self.trace_message(' removing side effect parent %s from the pending children set\n' % + self.trace_node(n))) + while stack: + n = stack.pop() + waiting_parents = n.waiting_parents + n.waiting_parents = set() + stack = stack | waiting_parents + pending_children = pending_children - waiting_parents + + for p in waiting_parents: + p.ref_count = p.ref_count - 1 + if T: T.write(self.trace_message(' removing parent %s from the pending children set\n' % + self.trace_node(p))) + for p in parents: p.ref_count = p.ref_count - 1 if T: T.write(self.trace_message(' removing parent %s from the pending children set\n' % diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py index d237d60a..430b56d0 100644 --- a/src/engine/SCons/TaskmasterTests.py +++ b/src/engine/SCons/TaskmasterTests.py @@ -34,6 +34,7 @@ import TestUnit import SCons.Taskmaster import SCons.Errors +import SCons.Job built_text = None @@ -181,8 +182,17 @@ class Node(object): wp.add(node) return 1 + def add_to_waiting_s_e(self, node): + self.waiting_s_e.add(node) + def get_state(self): return self.state + + def get_side_effects(self): + return self.side_effects + + def get_waiting_s_e(self): + return self.waiting_s_e def set_state(self, state): self.state = state @@ -235,7 +245,7 @@ class Node(object): def get_all_prerequisites(self): return [] def get_action_side_effects(self): - return [] + return [se for t in self.targets for se in t.side_effects] self.executor = Executor() self.executor.targets = self.targets return self.executor @@ -1007,6 +1017,26 @@ class TaskmasterTestCase(unittest.TestCase): t.execute() assert built_text is None, built_text assert cache_text == ["n7 retrieved", "n8 retrieved"], cache_text + + def test_pending_children_side_effects(self): + n1 = Node("n1") + n2 = Node("n2") + n3 = Node("n3") + n4 = Node("n4") + side_effect = Node("se") + + def build_error(): + import time; time.sleep(2) + raise SystemError("Node failed.") + n1.build = build_error + n1.side_effects = [side_effect] + n2.side_effects = [side_effect] + + n3.kids = [n2] + n4.kids = [n1, n2, n3] + tm = SCons.Taskmaster.Taskmaster([n4]) + jobs = SCons.Job.Jobs(2, tm) + jobs.run() def test_cached_execute(self): """Test executing a task with cached targets |