forked from mirror/waf
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			104 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			104 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
#! /usr/bin/env python
 | 
						|
 | 
						|
# The following example shows how several build processes can collaborate
 | 
						|
# to stop spawning new processes when a special task of type K is executed
 | 
						|
# this may be useful for link tasks for example
 | 
						|
 | 
						|
def options(opt):
 | 
						|
	opt.add_option('--loops', action='store', type='int', default=5, help='amount of cpu-intensive loops to perform')
 | 
						|
 | 
						|
def configure(conf):
 | 
						|
	busy = conf.path.find_node('look_busy.py').abspath()
 | 
						|
	conf.env.NOT_BUSY = ('%s 0' % busy).split()
 | 
						|
	conf.env.VERY_BUSY = ('%s %d' % (busy, conf.options.loops)).split()
 | 
						|
 | 
						|
def build(bld):
 | 
						|
	bld.link_limit = 1
 | 
						|
	bld.lockfile = bld.path.parent.make_node('busy_lock.txt').abspath()
 | 
						|
	for i in range(2):
 | 
						|
		for k in range(5):
 | 
						|
			bld(rule='${NOT_BUSY}', always=True)
 | 
						|
 | 
						|
		bld(rule='${VERY_BUSY}', always=True, exclusive=True)
 | 
						|
 | 
						|
		for k in range(10):
 | 
						|
			bld(rule='${NOT_BUSY}', always=True)
 | 
						|
 | 
						|
import os, fcntl, threading, errno, time
 | 
						|
from waflib import Task
 | 
						|
 | 
						|
lock = threading.Lock()
 | 
						|
 | 
						|
def lock_maxjob(self):
 | 
						|
	# lock the file, telling other build processes to avoid spawining tasks during that time
 | 
						|
	while True:
 | 
						|
		try:
 | 
						|
			self.lockfd = os.open(self.generator.bld.lockfile, os.O_TRUNC | os.O_CREAT | os.O_RDWR)
 | 
						|
			fcntl.flock(self.lockfd, fcntl.LOCK_EX | fcntl.LOCK_NB)
 | 
						|
		except EnvironmentError as e:
 | 
						|
			if e.errno in (errno.EACCES, errno.EAGAIN):
 | 
						|
				time.sleep(0.3)
 | 
						|
				continue
 | 
						|
			raise
 | 
						|
		os.write(self.lockfd, "%d" % os.getpid())
 | 
						|
		self.start_time = time.time()
 | 
						|
		break
 | 
						|
 | 
						|
def release_maxjob(self):
 | 
						|
	# release the lock file
 | 
						|
	print("> long task %d" % (time.time() - self.start_time))
 | 
						|
	try:
 | 
						|
		os.remove(self.generator.bld.lockfile)
 | 
						|
		os.close(self.lockfd)
 | 
						|
	except OSError, e:
 | 
						|
		# of someone else has removed the lock... bad luck! but do not fail here
 | 
						|
		print "unexpected failure", e
 | 
						|
		pass
 | 
						|
 | 
						|
def wait_maxjob(self):
 | 
						|
	# wait on the lock file.. up to a certain limit
 | 
						|
	while True:
 | 
						|
		try:
 | 
						|
			ini = os.stat(self.generator.bld.lockfile).st_mtime
 | 
						|
		except OSError, e:
 | 
						|
			return
 | 
						|
		diff = time.time() - ini
 | 
						|
		if diff > 300: # stale lock file? wait 5 minutes
 | 
						|
			return
 | 
						|
		time.sleep(0.5)
 | 
						|
 | 
						|
# the method process is called by threads...
 | 
						|
def process2(self):
 | 
						|
 | 
						|
	if getattr(self.generator, 'exclusive', False):
 | 
						|
		lock.acquire()
 | 
						|
		try:
 | 
						|
			self.lock_maxjob()
 | 
						|
		finally:
 | 
						|
			lock.release()
 | 
						|
	else:
 | 
						|
		self.wait_maxjob()
 | 
						|
 | 
						|
	ret = self.process_bound_maxjobs()
 | 
						|
 | 
						|
	if getattr(self.generator, 'exclusive', False):
 | 
						|
		lock.acquire()
 | 
						|
		try:
 | 
						|
			self.release_maxjob()
 | 
						|
		finally:
 | 
						|
			lock.release()
 | 
						|
	return ret
 | 
						|
 | 
						|
def process(self):
 | 
						|
	try:
 | 
						|
		process2(self)
 | 
						|
	except Exception, e:
 | 
						|
		print type(e), e
 | 
						|
 | 
						|
Task.Task.process_bound_maxjobs = Task.Task.process
 | 
						|
Task.Task.process = process
 | 
						|
Task.Task.lock_maxjob = lock_maxjob
 | 
						|
Task.Task.release_maxjob = release_maxjob
 | 
						|
Task.Task.wait_maxjob = wait_maxjob
 | 
						|
 |