'Possibly sleep in order to limit the transfer rate.
Note that we sleep based on *prior* transfers rather than what we
may be about to transfer. The next transfer could put us under/over
and that will be rectified *after* that transfer. Net result is that
the average transfer rate will remain within bounds. Spiky behavior
or uneven rates among the threads could possibly bring the transfer
rate above the requested limit for short durations.
Args:
throttle_name: The name of the throttle to sleep on.  If None or
omitted, then sleep on all throttles.'

def Sleep(self, throttle_name=None):

    if (throttle_name is None):
        for throttle_name in self.throttles:
            self.Sleep(throttle_name=throttle_name)
        return
    self.VerifyThrottleName(throttle_name)
    thread = threading.currentThread()
    while True:
        duration = (self.get_time() - self.last_rotate[throttle_name])
        total = 0
        for count in self.prior_block[throttle_name].values():
            total += count
        if total:
            duration += self.ROTATE_PERIOD
        for count in self.transferred[throttle_name].values():
            total += count
        sleep_time = self._SleepTime(total, self.throttles[throttle_name], duration)
        if (sleep_time < MINIMUM_THROTTLE_SLEEP_DURATION):
            break
        logger.debug('[%s]    Throttling    on    %s.    Sleeping    for    %.1f    ms    (duration=%.1f    ms,    total=%d)', thread.getName(), throttle_name, (sleep_time * 1000), (duration * 1000), total)
        self.thread_sleep(sleep_time)
        if thread.exit_flag:
            break
        self._RotateCounts(throttle_name)
