|  | @@ -348,7 +348,7 @@ class Jobset(object):
 | 
	
		
			
				|  |  |    """Manages one run of jobs."""
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    def __init__(self, check_cancelled, maxjobs, newline_on_success, travis,
 | 
	
		
			
				|  |  | -               stop_on_failure, add_env, quiet_success):
 | 
	
		
			
				|  |  | +               stop_on_failure, add_env, quiet_success, max_time):
 | 
	
		
			
				|  |  |      self._running = set()
 | 
	
		
			
				|  |  |      self._check_cancelled = check_cancelled
 | 
	
		
			
				|  |  |      self._cancelled = False
 | 
	
	
		
			
				|  | @@ -360,6 +360,7 @@ class Jobset(object):
 | 
	
		
			
				|  |  |      self._stop_on_failure = stop_on_failure
 | 
	
		
			
				|  |  |      self._add_env = add_env
 | 
	
		
			
				|  |  |      self._quiet_success = quiet_success
 | 
	
		
			
				|  |  | +    self._max_time = max_time
 | 
	
		
			
				|  |  |      self.resultset = {}
 | 
	
		
			
				|  |  |      self._remaining = None
 | 
	
		
			
				|  |  |      self._start_time = time.time()
 | 
	
	
		
			
				|  | @@ -379,6 +380,12 @@ class Jobset(object):
 | 
	
		
			
				|  |  |    def start(self, spec):
 | 
	
		
			
				|  |  |      """Start a job. Return True on success, False on failure."""
 | 
	
		
			
				|  |  |      while True:
 | 
	
		
			
				|  |  | +      if self._max_time > 0 and time.time() - self._start_time > self._max_time:
 | 
	
		
			
				|  |  | +        skipped_job_result = JobResult()
 | 
	
		
			
				|  |  | +        skipped_job_result.state = 'SKIPPED'
 | 
	
		
			
				|  |  | +        message('SKIPPED', spec.shortname, do_newline=True)
 | 
	
		
			
				|  |  | +        self.resultset[spec.shortname] = [skipped_job_result]
 | 
	
		
			
				|  |  | +        return True
 | 
	
		
			
				|  |  |        if self.cancelled(): return False
 | 
	
		
			
				|  |  |        current_cpu_cost = self.cpu_cost()
 | 
	
		
			
				|  |  |        if current_cpu_cost == 0: break
 | 
	
	
		
			
				|  | @@ -474,7 +481,8 @@ def run(cmdlines,
 | 
	
		
			
				|  |  |          stop_on_failure=False,
 | 
	
		
			
				|  |  |          add_env={},
 | 
	
		
			
				|  |  |          skip_jobs=False,
 | 
	
		
			
				|  |  | -        quiet_success=False):
 | 
	
		
			
				|  |  | +        quiet_success=False,
 | 
	
		
			
				|  |  | +        max_time=-1):
 | 
	
		
			
				|  |  |    if skip_jobs:
 | 
	
		
			
				|  |  |      resultset = {}
 | 
	
		
			
				|  |  |      skipped_job_result = JobResult()
 | 
	
	
		
			
				|  | @@ -486,7 +494,7 @@ def run(cmdlines,
 | 
	
		
			
				|  |  |    js = Jobset(check_cancelled,
 | 
	
		
			
				|  |  |                maxjobs if maxjobs is not None else _DEFAULT_MAX_JOBS,
 | 
	
		
			
				|  |  |                newline_on_success, travis, stop_on_failure, add_env,
 | 
	
		
			
				|  |  | -              quiet_success)
 | 
	
		
			
				|  |  | +              quiet_success, max_time)
 | 
	
		
			
				|  |  |    for cmdline, remaining in tag_remaining(cmdlines):
 | 
	
		
			
				|  |  |      if not js.start(cmdline):
 | 
	
		
			
				|  |  |        break
 |