1 | #! /usr/bin/env python |
---|
2 | # encoding: utf-8 |
---|
3 | # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file |
---|
4 | |
---|
5 | import random,atexit |
---|
6 | try: |
---|
7 | from queue import Queue |
---|
8 | except ImportError: |
---|
9 | from Queue import Queue |
---|
10 | from waflib import Utils,Task,Errors,Logs |
---|
11 | GAP=10 |
---|
12 | class TaskConsumer(Utils.threading.Thread): |
---|
13 | def __init__(self): |
---|
14 | Utils.threading.Thread.__init__(self) |
---|
15 | self.ready=Queue() |
---|
16 | self.setDaemon(1) |
---|
17 | self.start() |
---|
18 | def run(self): |
---|
19 | try: |
---|
20 | self.loop() |
---|
21 | except Exception: |
---|
22 | pass |
---|
23 | def loop(self): |
---|
24 | while 1: |
---|
25 | tsk=self.ready.get() |
---|
26 | if not isinstance(tsk,Task.TaskBase): |
---|
27 | tsk(self) |
---|
28 | else: |
---|
29 | tsk.process() |
---|
30 | pool=Queue() |
---|
31 | def get_pool(): |
---|
32 | try: |
---|
33 | return pool.get(False) |
---|
34 | except Exception: |
---|
35 | return TaskConsumer() |
---|
36 | def put_pool(x): |
---|
37 | pool.put(x) |
---|
38 | def _free_resources(): |
---|
39 | global pool |
---|
40 | lst=[] |
---|
41 | while pool.qsize(): |
---|
42 | lst.append(pool.get()) |
---|
43 | for x in lst: |
---|
44 | x.ready.put(None) |
---|
45 | for x in lst: |
---|
46 | x.join() |
---|
47 | pool=None |
---|
48 | atexit.register(_free_resources) |
---|
49 | class Parallel(object): |
---|
50 | def __init__(self,bld,j=2): |
---|
51 | self.numjobs=j |
---|
52 | self.bld=bld |
---|
53 | self.outstanding=[] |
---|
54 | self.frozen=[] |
---|
55 | self.out=Queue(0) |
---|
56 | self.count=0 |
---|
57 | self.processed=1 |
---|
58 | self.stop=False |
---|
59 | self.error=[] |
---|
60 | self.biter=None |
---|
61 | self.dirty=False |
---|
62 | def get_next_task(self): |
---|
63 | if not self.outstanding: |
---|
64 | return None |
---|
65 | return self.outstanding.pop(0) |
---|
66 | def postpone(self,tsk): |
---|
67 | if random.randint(0,1): |
---|
68 | self.frozen.insert(0,tsk) |
---|
69 | else: |
---|
70 | self.frozen.append(tsk) |
---|
71 | def refill_task_list(self): |
---|
72 | while self.count>self.numjobs*GAP: |
---|
73 | self.get_out() |
---|
74 | while not self.outstanding: |
---|
75 | if self.count: |
---|
76 | self.get_out() |
---|
77 | elif self.frozen: |
---|
78 | try: |
---|
79 | cond=self.deadlock==self.processed |
---|
80 | except AttributeError: |
---|
81 | pass |
---|
82 | else: |
---|
83 | if cond: |
---|
84 | msg='check the build order for the tasks' |
---|
85 | for tsk in self.frozen: |
---|
86 | if not tsk.run_after: |
---|
87 | msg='check the methods runnable_status' |
---|
88 | break |
---|
89 | lst=[] |
---|
90 | for tsk in self.frozen: |
---|
91 | lst.append('%s\t-> %r'%(repr(tsk),[id(x)for x in tsk.run_after])) |
---|
92 | raise Errors.WafError('Deadlock detected: %s%s'%(msg,''.join(lst))) |
---|
93 | self.deadlock=self.processed |
---|
94 | if self.frozen: |
---|
95 | self.outstanding+=self.frozen |
---|
96 | self.frozen=[] |
---|
97 | elif not self.count: |
---|
98 | self.outstanding.extend(self.biter.next()) |
---|
99 | self.total=self.bld.total() |
---|
100 | break |
---|
101 | def add_more_tasks(self,tsk): |
---|
102 | if getattr(tsk,'more_tasks',None): |
---|
103 | self.outstanding+=tsk.more_tasks |
---|
104 | self.total+=len(tsk.more_tasks) |
---|
105 | def get_out(self): |
---|
106 | tsk=self.out.get() |
---|
107 | if not self.stop: |
---|
108 | self.add_more_tasks(tsk) |
---|
109 | self.count-=1 |
---|
110 | self.dirty=True |
---|
111 | return tsk |
---|
112 | def error_handler(self,tsk): |
---|
113 | if not self.bld.keep: |
---|
114 | self.stop=True |
---|
115 | self.error.append(tsk) |
---|
116 | def add_task(self,tsk): |
---|
117 | try: |
---|
118 | self.pool |
---|
119 | except AttributeError: |
---|
120 | self.init_task_pool() |
---|
121 | self.ready.put(tsk) |
---|
122 | def init_task_pool(self): |
---|
123 | pool=self.pool=[get_pool()for i in range(self.numjobs)] |
---|
124 | self.ready=Queue(0) |
---|
125 | def setq(consumer): |
---|
126 | consumer.ready=self.ready |
---|
127 | for x in pool: |
---|
128 | x.ready.put(setq) |
---|
129 | return pool |
---|
130 | def free_task_pool(self): |
---|
131 | def setq(consumer): |
---|
132 | consumer.ready=Queue(0) |
---|
133 | self.out.put(self) |
---|
134 | try: |
---|
135 | pool=self.pool |
---|
136 | except AttributeError: |
---|
137 | pass |
---|
138 | else: |
---|
139 | for x in pool: |
---|
140 | self.ready.put(setq) |
---|
141 | for x in pool: |
---|
142 | self.get_out() |
---|
143 | for x in pool: |
---|
144 | put_pool(x) |
---|
145 | self.pool=[] |
---|
146 | def start(self): |
---|
147 | self.total=self.bld.total() |
---|
148 | while not self.stop: |
---|
149 | self.refill_task_list() |
---|
150 | tsk=self.get_next_task() |
---|
151 | if not tsk: |
---|
152 | if self.count: |
---|
153 | continue |
---|
154 | else: |
---|
155 | break |
---|
156 | if tsk.hasrun: |
---|
157 | self.processed+=1 |
---|
158 | continue |
---|
159 | if self.stop: |
---|
160 | break |
---|
161 | try: |
---|
162 | st=tsk.runnable_status() |
---|
163 | except Exception: |
---|
164 | self.processed+=1 |
---|
165 | tsk.err_msg=Utils.ex_stack() |
---|
166 | if not self.stop and self.bld.keep: |
---|
167 | tsk.hasrun=Task.SKIPPED |
---|
168 | if self.bld.keep==1: |
---|
169 | if Logs.verbose>1 or not self.error: |
---|
170 | self.error.append(tsk) |
---|
171 | self.stop=True |
---|
172 | else: |
---|
173 | if Logs.verbose>1: |
---|
174 | self.error.append(tsk) |
---|
175 | continue |
---|
176 | tsk.hasrun=Task.EXCEPTION |
---|
177 | self.error_handler(tsk) |
---|
178 | continue |
---|
179 | if st==Task.ASK_LATER: |
---|
180 | self.postpone(tsk) |
---|
181 | elif st==Task.SKIP_ME: |
---|
182 | self.processed+=1 |
---|
183 | tsk.hasrun=Task.SKIPPED |
---|
184 | self.add_more_tasks(tsk) |
---|
185 | else: |
---|
186 | tsk.position=(self.processed,self.total) |
---|
187 | self.count+=1 |
---|
188 | tsk.master=self |
---|
189 | self.processed+=1 |
---|
190 | if self.numjobs==1: |
---|
191 | tsk.process() |
---|
192 | else: |
---|
193 | self.add_task(tsk) |
---|
194 | while self.error and self.count: |
---|
195 | self.get_out() |
---|
196 | assert(self.count==0 or self.stop) |
---|
197 | self.free_task_pool() |
---|