def sleep(seconds=0, ref=True): """ Put the current greenlet to sleep for at least *seconds*. *seconds* may be specified as an integer, or a float if fractional seconds are desired. .. tip:: In the current implementation, a value of 0 (the default) means to yield execution to any other runnable greenlets, but this greenlet may be scheduled again before the event loop cycles (in an extreme case, a greenlet that repeatedly sleeps with 0 can prevent greenlets that are ready to do I/O from being scheduled for some (small) period of time); a value greater than 0, on the other hand, will delay running this greenlet until the next iteration of the loop. If *ref* is False, the greenlet running ``sleep()`` will not prevent :func:`gevent.wait` from exiting. .. versionchanged:: 1.3a1 Sleeping with a value of 0 will now be bounded to approximately block the loop for no longer than :func:`gevent.getswitchinterval`. .. seealso:: :func:`idle` """ hub = _get_hub_noargs() loop = hub.loop if seconds <= 0: waiter = Waiter(hub) loop.run_callback(waiter.switch, None) waiter.get() else: with loop.timer(seconds, ref=ref) as t: hub.wait(t)
def join(self, timeout=None): """Wait for the event loop to finish. Exits only when there are no more spawned greenlets, started servers, active timeouts or watchers. If *timeout* is provided, wait no longer for the specified number of seconds. Returns True if exited because the loop finished execution. Returns False if exited because of timeout expired. """ assert getcurrent( ) is self.parent, "only possible from the MAIN greenlet" if self.dead: return True waiter = Waiter(self) if timeout is not None: timeout = self.loop.timer(timeout, ref=False) timeout.start(waiter.switch, None) try: try: waiter.get() except LoopExit: return True finally: if timeout is not None: timeout.stop() timeout.close() return False
def join(self, timeout=None): """ Wait for the event loop to finish. Exits only when there are no more spawned greenlets, started servers, active timeouts or watchers. .. caution:: This doesn't clean up all resources associated with the hub. For that, see :meth:`destroy`. :param float timeout: If *timeout* is provided, wait no longer than the specified number of seconds. :return: `True` if this method returns because the loop finished execution. Or `False` if the timeout expired. """ assert getcurrent( ) is self.parent, "only possible from the MAIN greenlet" if self.dead: return True waiter = Waiter(self) if timeout is not None: timeout = self.loop.timer(timeout, ref=False) timeout.start(waiter.switch, None) try: try: # Switch to the hub greenlet and let it continue. # Since we're the parent greenlet of the hub, when it exits # by `parent.throw(LoopExit)`, control will resume here. # If the timer elapses, however, ``waiter.switch()`` is called and # again control resumes here, but without an exception. waiter.get() except LoopExit: # Control will immediately be returned to this greenlet. return True finally: # Clean up as much junk as we can. There is a small cycle in the frames, # and it won't be GC'd. # this greenlet -> this frame # this greenlet -> the exception that was thrown # the exception that was thrown -> a bunch of other frames, including this frame. # some frame calling self.run() -> self del waiter # this frame -> waiter -> self del self # this frame -> self if timeout is not None: timeout.stop() timeout.close() del timeout return False