summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilippe Coval <philippe.coval@osg.samsung.com>2017-08-27 15:10:01 +0200
committerPhilippe Coval <philippe.coval@osg.samsung.com>2017-10-10 11:24:00 +0200
commitbe26e6e43be56e814af1372f203e1b2748eebb04 (patch)
treeb81b6e7c13b6ea6c21277405b1cd21ec07c40f43
parent81c02354dfd7634708eb79547e9448150cc016a6 (diff)
downloadscons-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.py21
-rw-r--r--src/engine/SCons/TaskmasterTests.py32
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