wscript 1.7 KB

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