diff options
Diffstat (limited to 'third_party/waf/waflib/extras/smart_continue.py')
-rw-r--r-- | third_party/waf/waflib/extras/smart_continue.py | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/third_party/waf/waflib/extras/smart_continue.py b/third_party/waf/waflib/extras/smart_continue.py new file mode 100644 index 00000000000..8c171a8d96c --- /dev/null +++ b/third_party/waf/waflib/extras/smart_continue.py @@ -0,0 +1,80 @@ +#! /usr/bin/env python +# Thomas Nagy, 2011 + +# Try to cancel the tasks that cannot run with the option -k when an error occurs: +# 1 direct file dependencies +# 2 tasks listed in the before/after/ext_in/ext_out attributes + +from waflib import Task, Runner + +Task.CANCELED = 4 + +def cancel_next(self, tsk): + if not isinstance(tsk, Task.TaskBase): + return + if tsk.hasrun >= Task.SKIPPED: + # normal execution, no need to do anything here + return + + try: + canceled_tasks, canceled_nodes = self.canceled_tasks, self.canceled_nodes + except AttributeError: + canceled_tasks = self.canceled_tasks = set([]) + canceled_nodes = self.canceled_nodes = set([]) + + try: + canceled_nodes.update(tsk.outputs) + except AttributeError: + pass + + try: + canceled_tasks.add(tsk) + except AttributeError: + pass + +def get_out(self): + tsk = self.out.get() + if not self.stop: + self.add_more_tasks(tsk) + self.count -= 1 + self.dirty = True + self.cancel_next(tsk) # new code + +def error_handler(self, tsk): + if not self.bld.keep: + self.stop = True + self.error.append(tsk) + self.cancel_next(tsk) # new code + +Runner.Parallel.cancel_next = cancel_next +Runner.Parallel.get_out = get_out +Runner.Parallel.error_handler = error_handler + +def get_next_task(self): + tsk = self.get_next_task_smart_continue() + if not tsk: + return tsk + + try: + canceled_tasks, canceled_nodes = self.canceled_tasks, self.canceled_nodes + except AttributeError: + pass + else: + # look in the tasks that this one is waiting on + # if one of them was canceled, cancel this one too + for x in tsk.run_after: + if x in canceled_tasks: + tsk.hasrun = Task.CANCELED + self.cancel_next(tsk) + break + else: + # so far so good, now consider the nodes + for x in getattr(tsk, 'inputs', []) + getattr(tsk, 'deps', []): + if x in canceled_nodes: + tsk.hasrun = Task.CANCELED + self.cancel_next(tsk) + break + return tsk + +Runner.Parallel.get_next_task_smart_continue = Runner.Parallel.get_next_task +Runner.Parallel.get_next_task = get_next_task |