|  | @@ -60,10 +60,16 @@ class Control(six.with_metaclass(abc.ABCMeta)):
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  class PauseFailControl(Control):
 | 
	
		
			
				|  |  | -  """A Control that can be used to pause or fail code under control."""
 | 
	
		
			
				|  |  | +  """A Control that can be used to pause or fail code under control.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  This object is only safe for use from two threads: one of the system under
 | 
	
		
			
				|  |  | +  test calling control and the other from the test system calling pause,
 | 
	
		
			
				|  |  | +  block_until_paused, and fail.
 | 
	
		
			
				|  |  | +  """
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    def __init__(self):
 | 
	
		
			
				|  |  |      self._condition = threading.Condition()
 | 
	
		
			
				|  |  | +    self._pause = False
 | 
	
		
			
				|  |  |      self._paused = False
 | 
	
		
			
				|  |  |      self._fail = False
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -72,19 +78,31 @@ class PauseFailControl(Control):
 | 
	
		
			
				|  |  |        if self._fail:
 | 
	
		
			
				|  |  |          raise Defect()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -      while self._paused:
 | 
	
		
			
				|  |  | +      while self._pause:
 | 
	
		
			
				|  |  | +        self._paused = True
 | 
	
		
			
				|  |  | +        self._condition.notify_all()
 | 
	
		
			
				|  |  |          self._condition.wait()
 | 
	
		
			
				|  |  | +      self._paused = False
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    @contextlib.contextmanager
 | 
	
		
			
				|  |  |    def pause(self):
 | 
	
		
			
				|  |  |      """Pauses code under control while controlling code is in context."""
 | 
	
		
			
				|  |  |      with self._condition:
 | 
	
		
			
				|  |  | -      self._paused = True
 | 
	
		
			
				|  |  | +      self._pause = True
 | 
	
		
			
				|  |  |      yield
 | 
	
		
			
				|  |  |      with self._condition:
 | 
	
		
			
				|  |  | -      self._paused = False
 | 
	
		
			
				|  |  | +      self._pause = False
 | 
	
		
			
				|  |  |        self._condition.notify_all()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  def block_until_paused(self):
 | 
	
		
			
				|  |  | +    """Blocks controlling code until code under control is paused.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    May only be called within the context of a pause call.
 | 
	
		
			
				|  |  | +    """
 | 
	
		
			
				|  |  | +    with self._condition:
 | 
	
		
			
				|  |  | +      while not self._paused:
 | 
	
		
			
				|  |  | +        self._condition.wait()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    @contextlib.contextmanager
 | 
	
		
			
				|  |  |    def fail(self):
 | 
	
		
			
				|  |  |      """Fails code under control while controlling code is in context."""
 |