wscript (1703B)
1 #! /usr/bin/env python 2 3 # the Task class attribute "maxjobs" was deprecated in Waf 1.6 4 # limiting the amount of jobs is commonly done by adding sequential 5 # barriers (build groups) or even locks. But the feature might be 6 # necessary in very few corner cases 7 8 # in the following examples, remember that the method run() is the only 9 # one actually executed by threads 10 11 def configure(conf): 12 pass 13 14 def build(bld): 15 bld.jobs = 4 16 bld(source='foo.a bar.a truc.a') 17 18 19 import threading, time 20 from waflib.TaskGen import extension 21 from waflib import Task 22 23 @extension('.a') 24 def process_a_files(self, node): 25 self.create_task('a_to_b', node, node.change_ext('b')) 26 self.create_task('b_to_c', node.change_ext('b'), node.change_ext('c')) 27 28 class a_to_b(Task.Task): 29 # classical way, using a lock or a semaphore 30 # in this case, at most 2 tasks can execute at a time 31 # this may lead to build starvation, as may tasks can get stalled while processing 32 33 lock = threading.Semaphore(2) 34 def run(self): 35 try: 36 self.lock.acquire() 37 for i in range(5): 38 print('a to b %r' % id(self)) 39 time.sleep(1) 40 self.outputs[0].write('done') 41 finally: 42 self.lock.release() 43 44 45 class b_to_c(Task.Task): 46 # this will enable other tasks to run concurrently, and without additional locks 47 48 active = [] 49 def runnable_status(self): 50 ret = Task.Task.runnable_status(self) 51 if ret == Task.RUN_ME: 52 self.active = [tsk for tsk in self.active if not tsk.hasrun] 53 if len(self.active) < 2: 54 self.active.append(self) 55 else: 56 # too many tasks are still active, wait 57 ret = Task.ASK_LATER 58 return ret 59 60 def run(self): 61 for i in range(5): 62 print('b to c %r' % id(self)) 63 time.sleep(1) 64 self.outputs[0].write('done') 65