summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2002-11-27 16:51:08 (GMT)
committerSteven Knight <knight@baldmt.com>2002-11-27 16:51:08 (GMT)
commit4e5b73e5e77664749549fc5082550f82c4064604 (patch)
tree31c9ed8a994e13380e34a0d069329c95c7821f29 /src
parent8cfa91f6e3337cef06ea55d08389f2d83d1faee7 (diff)
downloadSCons-4e5b73e5e77664749549fc5082550f82c4064604.zip
SCons-4e5b73e5e77664749549fc5082550f82c4064604.tar.gz
SCons-4e5b73e5e77664749549fc5082550f82c4064604.tar.bz2
Serialize calls to Node.prepare() (Anthony Roach)
Diffstat (limited to 'src')
-rw-r--r--src/engine/SCons/Job.py4
-rw-r--r--src/engine/SCons/JobTests.py22
-rw-r--r--src/engine/SCons/Script/__init__.py64
-rw-r--r--src/engine/SCons/Taskmaster.py15
-rw-r--r--src/engine/SCons/TaskmasterTests.py8
5 files changed, 76 insertions, 37 deletions
diff --git a/src/engine/SCons/Job.py b/src/engine/SCons/Job.py
index 21f4617..c06cf23 100644
--- a/src/engine/SCons/Job.py
+++ b/src/engine/SCons/Job.py
@@ -123,6 +123,7 @@ class Serial:
break
try:
+ task.prepare()
task.execute()
except KeyboardInterrupt:
raise
@@ -243,8 +244,9 @@ class Parallel:
if task == None:
break
- cv.release()
try:
+ task.prepare()
+ cv.release()
try:
task.execute()
finally:
diff --git a/src/engine/SCons/JobTests.py b/src/engine/SCons/JobTests.py
index 55e5f0f..c97ad55 100644
--- a/src/engine/SCons/JobTests.py
+++ b/src/engine/SCons/JobTests.py
@@ -59,8 +59,15 @@ class Task:
self.i = i
self.taskmaster = taskmaster
self.was_executed = 0
+ self.was_prepared = 0
+
+ def prepare(self):
+ self.was_prepared = 1
def execute(self):
+ self.taskmaster.test_case.failUnless(self.was_prepared,
+ "the task wasn't prepared")
+
self.taskmaster.guard.acquire()
self.taskmaster.begin_list.append(self.i)
self.taskmaster.guard.release()
@@ -78,6 +85,8 @@ class Task:
def executed(self):
self.taskmaster.num_executed = self.taskmaster.num_executed + 1
+ self.taskmaster.test_case.failUnless(self.was_prepared,
+ "the task wasn't prepared")
self.taskmaster.test_case.failUnless(self.was_executed,
"the task wasn't really executed")
self.taskmaster.test_case.failUnless(self.__class__ is Task,
@@ -86,12 +95,19 @@ class Task:
def failed(self):
self.taskmaster.num_failed = self.taskmaster.num_failed + 1
self.taskmaster.stop = 1
+ self.taskmaster.test_case.failUnless(self.was_prepared,
+ "the task wasn't prepared")
+
class ExceptionTask:
"""A dummy task class for testing purposes."""
def __init__(self, i, taskmaster):
self.taskmaster = taskmaster
+ self.was_prepared = 0
+
+ def prepare(self):
+ self.was_prepared = 1
def execute(self):
raise "exception"
@@ -99,6 +115,8 @@ class ExceptionTask:
def executed(self):
self.taskmaster.num_executed = self.taskmaster.num_executed + 1
+ self.taskmaster.test_case.failUnless(self.was_prepared,
+ "the task wasn't prepared")
self.taskmaster.test_case.failUnless(self.was_executed,
"the task wasn't really executed")
self.taskmaster.test_case.failUnless(self.__class__ is Task,
@@ -107,6 +125,8 @@ class ExceptionTask:
def failed(self):
self.taskmaster.num_failed = self.taskmaster.num_failed + 1
self.taskmaster.stop = 1
+ self.taskmaster.test_case.failUnless(self.was_prepared,
+ "the task wasn't prepared")
class Taskmaster:
"""A dummy taskmaster class for testing the job classes."""
@@ -147,7 +167,7 @@ class Taskmaster:
def all_tasks_are_iterated(self):
return self.num_iterated == self.num_tasks
-
+
def is_blocked(self):
# simulate blocking tasks
return self.num_iterated - self.num_executed >= max(num_jobs/2, 2)
diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py
index dd44621..57d0eeb 100644
--- a/src/engine/SCons/Script/__init__.py
+++ b/src/engine/SCons/Script/__init__.py
@@ -77,37 +77,14 @@ class BuildTask(SCons.Taskmaster.Task):
if self.top:
display('scons: "%s" is up to date.' % str(self.targets[0]))
else:
- try:
- self.targets[0].prepare()
- if print_time:
- start_time = time.time()
- self.targets[0].build()
- if print_time:
- finish_time = time.time()
- global command_time
- command_time = command_time+finish_time-start_time
- print "Command execution time: %f seconds"%(finish_time-start_time)
-
- except BuildError, e:
- sys.stderr.write("scons: *** [%s] %s\n" % (e.node, e.errstr))
- if e.errstr == 'Exception':
- traceback.print_exception(e.args[0], e.args[1],
- e.args[2])
- raise
- except UserError, e:
- # We aren't being called out of a user frame, so
- # don't try to walk the stack, just print the error.
- sys.stderr.write("\nSCons error: %s\n" % e)
- raise
- except StopError, e:
- s = str(e)
- if not keep_going_on_error:
- s = s + ' Stop.'
- sys.stderr.write("scons: *** %s\n" % s)
- raise
- except:
- sys.stderr.write("scons: *** %s\n" % sys.exc_value)
- raise
+ if print_time:
+ start_time = time.time()
+ self.targets[0].build()
+ if print_time:
+ finish_time = time.time()
+ global command_time
+ command_time = command_time+finish_time-start_time
+ print "Command execution time: %f seconds"%(finish_time-start_time)
def executed(self):
SCons.Taskmaster.Task.executed(self)
@@ -124,6 +101,25 @@ class BuildTask(SCons.Taskmaster.Task):
def failed(self):
global exit_status
+
+ e = sys.exc_value
+ if sys.exc_type == BuildError:
+ sys.stderr.write("scons: *** [%s] %s\n" % (e.node, e.errstr))
+ if e.errstr == 'Exception':
+ traceback.print_exception(e.args[0], e.args[1],
+ e.args[2])
+ elif sys.exc_type == UserError:
+ # We aren't being called out of a user frame, so
+ # don't try to walk the stack, just print the error.
+ sys.stderr.write("\nSCons error: %s\n" % e)
+ elif sys.exc_type == StopError:
+ s = str(e)
+ if not keep_going_on_error:
+ s = s + ' Stop.'
+ sys.stderr.write("scons: *** %s\n" % s)
+ else:
+ sys.stderr.write("scons: *** %s\n" % e)
+
if ignore_errors:
SCons.Taskmaster.Task.executed(self)
elif keep_going_on_error:
@@ -152,8 +148,14 @@ class CleanTask(SCons.Taskmaster.Task):
execute = remove
+ def prepare(self):
+ pass
+
class QuestionTask(SCons.Taskmaster.Task):
"""An SCons task for the -q (question) option."""
+ def prepare(self):
+ pass
+
def execute(self):
if self.targets[0].get_state() != SCons.Node.up_to_date:
global exit_status
diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py
index bf2d918..a32def4 100644
--- a/src/engine/SCons/Taskmaster.py
+++ b/src/engine/SCons/Taskmaster.py
@@ -60,12 +60,19 @@ class Task:
self.top = top
self.node = node
- def execute(self):
- # This methods is called from multiple threads in
- # a parallel build, so only do thread safe stuff here.
- # Do thread unsafe stuff in executed() or failed().
+
+ def prepare(self):
+ """Called just before the task is executed."""
if self.targets[0].get_state() != SCons.Node.up_to_date:
self.targets[0].prepare()
+
+ def execute(self):
+ """Called to execute the task.
+
+ This methods is called from multiple threads in
+ a parallel build, so only do thread safe stuff here.
+ Do thread unsafe stuff in prepare(), executed() or failed()."""
+ if self.targets[0].get_state() != SCons.Node.up_to_date:
self.targets[0].build()
def get_target(self):
diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py
index f3bf182..23d7e0a 100644
--- a/src/engine/SCons/TaskmasterTests.py
+++ b/src/engine/SCons/TaskmasterTests.py
@@ -124,6 +124,7 @@ class TaskmasterTestCase(unittest.TestCase):
n1 = Node("n1")
tm = SCons.Taskmaster.Taskmaster([n1, n1])
t = tm.next_task()
+ t.prepare()
t.execute()
t = tm.next_task()
assert t == None
@@ -135,16 +136,19 @@ class TaskmasterTestCase(unittest.TestCase):
tm = SCons.Taskmaster.Taskmaster([n3])
t = tm.next_task()
+ t.prepare()
t.execute()
assert built_text == "n1 built", built_text
t.executed()
t = tm.next_task()
+ t.prepare()
t.execute()
assert built_text == "n2 built", built_text
t.executed()
t = tm.next_task()
+ t.prepare()
t.execute()
assert built_text == "n3 built", built_text
t.executed()
@@ -176,16 +180,19 @@ class TaskmasterTestCase(unittest.TestCase):
tasker = MyTask, calc = MyCalc())
t = tm.next_task()
+ t.prepare()
t.execute()
assert built_text == "n1 up-to-date", built_text
t.executed()
t = tm.next_task()
+ t.prepare()
t.execute()
assert built_text == "n2 up-to-date", built_text
t.executed()
t = tm.next_task()
+ t.prepare()
t.execute()
assert built_text == "n3 up-to-date top", built_text
t.executed()
@@ -372,6 +379,7 @@ class TaskmasterTestCase(unittest.TestCase):
tm = SCons.Taskmaster.Taskmaster([n3])
t = tm.next_task()
+ t.prepare()
t.execute()
assert built_text == "n1 built", built_text
t.executed()