summaryrefslogtreecommitdiff
path: root/third_party/waf/waflib/extras/smart_continue.py
blob: 8c171a8d96c8acb836be8aff7e8000750e6729d4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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