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 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
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: # Sleeping is expected to be an "absolute" measure with # respect to time.time(), not a relative measure, so it's # important to update the loop's notion of now before we start loop.update_now() hub.wait(t)