#! /usr/bin/env python # encoding: utf-8 import sys if sys.hexversion < 0x020400f0: from sets import Set as set import sys,random,time,threading,traceback try:from Queue import Queue except ImportError:from queue import Queue import Build,Utils,Logs,Options from Logs import debug,error from Constants import* GAP=15 run_old=threading.Thread.run def run(*args,**kwargs): try: run_old(*args,**kwargs) except(KeyboardInterrupt,SystemExit): raise except: sys.excepthook(*sys.exc_info()) threading.Thread.run=run class TaskConsumer(threading.Thread): ready=Queue(0) consumers=[] def __init__(self): threading.Thread.__init__(self) self.setDaemon(1) self.start() def run(self): try: self.loop() except: pass def loop(self): while 1: tsk=TaskConsumer.ready.get() m=tsk.master if m.stop: m.out.put(tsk) continue try: tsk.generator.bld.printout(tsk.display()) if tsk.__class__.stat:ret=tsk.__class__.stat(tsk) else:ret=tsk.call_run() except Exception,e: tsk.err_msg=Utils.ex_stack() tsk.hasrun=EXCEPTION m.error_handler(tsk) m.out.put(tsk) continue if ret: tsk.err_code=ret tsk.hasrun=CRASHED else: try: tsk.post_run() except Utils.WafError: pass except Exception: tsk.err_msg=Utils.ex_stack() tsk.hasrun=EXCEPTION else: tsk.hasrun=SUCCESS if tsk.hasrun!=SUCCESS: m.error_handler(tsk) m.out.put(tsk) class Parallel(object): def __init__(self,bld,j=2): self.numjobs=j self.manager=bld.task_manager self.manager.current_group=0 self.total=self.manager.total() self.outstanding=[] self.maxjobs=MAXJOBS self.frozen=[] self.out=Queue(0) self.count=0 self.processed=1 self.stop=False self.error=False def get_next(self): if not self.outstanding: return None return self.outstanding.pop(0) def postpone(self,tsk): if random.randint(0,1): self.frozen.insert(0,tsk) else: self.frozen.append(tsk) def refill_task_list(self): while self.count>self.numjobs+GAP or self.count>=self.maxjobs: self.get_out() while not self.outstanding: if self.count: self.get_out() if self.frozen: self.outstanding+=self.frozen self.frozen=[] elif not self.count: (jobs,tmp)=self.manager.get_next_set() if jobs!=None:self.maxjobs=jobs if tmp:self.outstanding+=tmp break def get_out(self): ret=self.out.get() self.manager.add_finished(ret) if not self.stop and getattr(ret,'more_tasks',None): self.outstanding+=ret.more_tasks self.total+=len(ret.more_tasks) self.count-=1 def error_handler(self,tsk): if not Options.options.keep: self.stop=True self.error=True def start(self): if TaskConsumer.consumers: while len(TaskConsumer.consumers)