waf

FORK: waf with some random patches
git clone https://git.neptards.moe/neptards/waf.git
Log | Files | Refs | README

wscript (2709B)


      1 #! /usr/bin/env python
      2 
      3 # The following example shows how several build processes can collaborate
      4 # to stop spawning new processes when a special task of type K is executed
      5 # this may be useful for link tasks for example
      6 
      7 def options(opt):
      8 	opt.add_option('--loops', action='store', type='int', default=5, help='amount of cpu-intensive loops to perform')
      9 
     10 def configure(conf):
     11 	busy = conf.path.find_node('look_busy.py').abspath()
     12 	conf.env.NOT_BUSY = ('%s 0' % busy).split()
     13 	conf.env.VERY_BUSY = ('%s %d' % (busy, conf.options.loops)).split()
     14 
     15 def build(bld):
     16 	bld.link_limit = 1
     17 	bld.lockfile = bld.path.parent.make_node('busy_lock.txt').abspath()
     18 	for i in range(2):
     19 		for k in range(5):
     20 			bld(rule='${NOT_BUSY}', always=True)
     21 
     22 		bld(rule='${VERY_BUSY}', always=True, exclusive=True)
     23 
     24 		for k in range(10):
     25 			bld(rule='${NOT_BUSY}', always=True)
     26 
     27 import os, fcntl, threading, errno, time
     28 from waflib import Task
     29 
     30 lock = threading.Lock()
     31 
     32 def lock_maxjob(self):
     33 	# lock the file, telling other build processes to avoid spawining tasks during that time
     34 	while True:
     35 		try:
     36 			self.lockfd = os.open(self.generator.bld.lockfile, os.O_TRUNC | os.O_CREAT | os.O_RDWR)
     37 			fcntl.flock(self.lockfd, fcntl.LOCK_EX | fcntl.LOCK_NB)
     38 		except EnvironmentError as e:
     39 			if e.errno in (errno.EACCES, errno.EAGAIN):
     40 				time.sleep(0.3)
     41 				continue
     42 			raise
     43 		os.write(self.lockfd, "%d" % os.getpid())
     44 		self.start_time = time.time()
     45 		break
     46 
     47 def release_maxjob(self):
     48 	# release the lock file
     49 	print("> long task %d" % (time.time() - self.start_time))
     50 	try:
     51 		os.remove(self.generator.bld.lockfile)
     52 		os.close(self.lockfd)
     53 	except OSError, e:
     54 		# of someone else has removed the lock... bad luck! but do not fail here
     55 		print "unexpected failure", e
     56 		pass
     57 
     58 def wait_maxjob(self):
     59 	# wait on the lock file.. up to a certain limit
     60 	while True:
     61 		try:
     62 			ini = os.stat(self.generator.bld.lockfile).st_mtime
     63 		except OSError, e:
     64 			return
     65 		diff = time.time() - ini
     66 		if diff > 300: # stale lock file? wait 5 minutes
     67 			return
     68 		time.sleep(0.5)
     69 
     70 # the method process is called by threads...
     71 def process2(self):
     72 
     73 	if getattr(self.generator, 'exclusive', False):
     74 		lock.acquire()
     75 		try:
     76 			self.lock_maxjob()
     77 		finally:
     78 			lock.release()
     79 	else:
     80 		self.wait_maxjob()
     81 
     82 	ret = self.process_bound_maxjobs()
     83 
     84 	if getattr(self.generator, 'exclusive', False):
     85 		lock.acquire()
     86 		try:
     87 			self.release_maxjob()
     88 		finally:
     89 			lock.release()
     90 	return ret
     91 
     92 def process(self):
     93 	try:
     94 		process2(self)
     95 	except Exception, e:
     96 		print type(e), e
     97 
     98 Task.Task.process_bound_maxjobs = Task.Task.process
     99 Task.Task.process = process
    100 Task.Task.lock_maxjob = lock_maxjob
    101 Task.Task.release_maxjob = release_maxjob
    102 Task.Task.wait_maxjob = wait_maxjob
    103