Stops the interval.

    If a timeout is provided and stop returns False then the thread is
    effectively abandoned in whatever state it was in (presumably dead-locked).

    Args:
      timeout_s: The time in seconds to wait on the thread to finish.  By
          default it's forever.
    Returns:
      False if a timeout was provided and we timed out.

def stop(self, timeout_s=None):
    """Stops the interval.

    If a timeout is provided and stop returns False then the thread is
    effectively abandoned in whatever state it was in (presumably dead-locked).

    Args:
      timeout_s: The time in seconds to wait on the thread to finish.  By
          default it's forever.
    Returns:
      False if a timeout was provided and we timed out.
    """
    self.stopped.set()
    if self.thread:
      self.thread.join(timeout_s)
      return not self.thread.isAlive()
    else:
      return True