Beispiel #1
0
def _spawn_startup(cb, args, kw, cancel=None):
    try:
        greenlet.getcurrent().parent.switch()
        cancel = None
    finally:
        if cancel is not None:
            cancel()
    return cb(*args, **kw)
Beispiel #2
0
 def switch(self):
     assert greenlet.getcurrent() is not self.greenlet, \
         "Cannot switch from MAINLOOP to MAINLOOP"
     try:
         greenlet.getcurrent().parent = self.greenlet
     except ValueError:
         pass
     return self.greenlet.switch()
Beispiel #3
0
 def switch(self):
     assert greenlet.getcurrent() is not self.greenlet, \
            "Cannot switch from MAINLOOP to MAINLOOP"
     try:
        greenlet.getcurrent().parent = self.greenlet
     except ValueError:
        pass
     return self.greenlet.switch()
Beispiel #4
0
 def _send_tasklet(self, *args):
     try:
         t = self._tasklet
     except AttributeError:
         t = self._tasklet = greenlet.greenlet(self._tasklet_loop)
         t.switch()
     if args:
         return t.switch((1, greenlet.getcurrent(), args))
     else:
         return t.switch((-1, greenlet.getcurrent(), args))
Beispiel #5
0
 def start(self):
     """Schedule the timeout.  This is called on construction, so
     it should not be called explicitly, unless the timer has been
     cancelled."""
     assert not self.pending, \
            '%r is already started; to restart it, cancel it first' % self
     if self.seconds is None: # "fake" timeout (never expires)
         self.timer = None
     elif self.exception is None or self.exception is False: # timeout that raises self
         self.timer = get_hub().schedule_call_global(
             self.seconds, greenlet.getcurrent().throw, self)
     else: # regular timeout with user-provided exception
         self.timer = get_hub().schedule_call_global(
             self.seconds, greenlet.getcurrent().throw, self.exception)
     return self
Beispiel #6
0
 def start(self):
     """Schedule the timeout.  This is called on construction, so
     it should not be called explicitly, unless the timer has been
     canceled."""
     assert not self.pending, \
            '%r is already started; to restart it, cancel it first' % self
     if self.seconds is None: # "fake" timeout (never expires)
         self.timer = None
     elif self.exception is None or isinstance(self.exception, bool): # timeout that raises self
         self.timer = get_hub().schedule_call_global(
             self.seconds, greenlet.getcurrent().throw, self)
     else: # regular timeout with user-provided exception
         self.timer = get_hub().schedule_call_global(
             self.seconds, greenlet.getcurrent().throw, self.exception)
     return self
Beispiel #7
0
def current_thread():
    g = greenlet.getcurrent()
    if not g:
        # Not currently in a greenthread, fall back to standard function
        return _fixup_thread(__orig_threading.current_thread())

    try:
        active = __threadlocal.active
    except AttributeError:
        active = __threadlocal.active = {}
    
    try:
        t = active[id(g)]
    except KeyError:
        # Add green thread to active if we can clean it up on exit
        def cleanup(g):
            del active[id(g)]
        try:
            g.link(cleanup)
        except AttributeError:
            # Not a GreenThread type, so there's no way to hook into
            # the green thread exiting. Fall back to the standard
            # function then.
            t = _fixup_thread(__orig_threading.currentThread())
        else:
            t = active[id(g)] = _GreenThread(g)

    return t
Beispiel #8
0
def current_thread():
    g = greenlet.getcurrent()
    if not g:
        # Not currently in a greenthread, fall back to standard function
        return _fixup_thread(__orig_threading.current_thread())

    try:
        active = __threadlocal.active
    except AttributeError:
        active = __threadlocal.active = {}

    try:
        t = active[id(g)]
    except KeyError:
        # Add green thread to active if we can clean it up on exit
        def cleanup(g):
            del active[id(g)]
        try:
            g.link(cleanup)
        except AttributeError:
            # Not a GreenThread type, so there's no way to hook into
            # the green thread exiting. Fall back to the standard
            # function then.
            t = _fixup_thread(__orig_threading.currentThread())
        else:
            t = active[id(g)] = _GreenThread(g)

    return t
Beispiel #9
0
 def abort(self, wait=True):
     self.schedule_call_global(0, self.greenlet.throw,
                               greenlet.GreenletExit)
     if wait:
         assert self.greenlet is not greenlet.getcurrent(
         ), "Can't abort with wait from inside the hub's greenlet."
         self.switch()
Beispiel #10
0
    def wait(self):
        """Wait until another coroutine calls :meth:`send`.
        Returns the value the other coroutine passed to
        :meth:`send`.

        >>> from eventlet import event
        >>> import eventlet
        >>> evt = event.Event()
        >>> def wait_on():
        ...    retval = evt.wait()
        ...    print("waited for {0}".format(retval))
        >>> _ = eventlet.spawn(wait_on)
        >>> evt.send('result')
        >>> eventlet.sleep(0)
        waited for result

        Returns immediately if the event has already
        occured.

        >>> evt.wait()
        'result'
        """
        current = greenlet.getcurrent()
        if self._result is NOT_USED:
            self._waiters.add(current)
            try:
                return hubs.get_hub().switch()
            finally:
                self._waiters.discard(current)
        if self._exc is not None:
            current.throw(*self._exc)
        return self._result
Beispiel #11
0
    def wait(self):
        """Wait until another coroutine calls :meth:`send`.
        Returns the value the other coroutine passed to
        :meth:`send`.

        >>> from eventlet import event
        >>> import eventlet
        >>> evt = event.Event()
        >>> def wait_on():
        ...    retval = evt.wait()
        ...    print "waited for", retval
        >>> _ = eventlet.spawn(wait_on)
        >>> evt.send('result')
        >>> eventlet.sleep(0)
        waited for result

        Returns immediately if the event has already
        occured.

        >>> evt.wait()
        'result'
        """
        current = greenlet.getcurrent()
        if self._result is NOT_USED:
            self._waiters.add(current)
            try:
                return hubs.get_hub().switch()
            finally:
                self._waiters.discard(current)
        if self._exc is not None:
            current.throw(*self._exc)
        return self._result
Beispiel #12
0
def g_log(*args):
    import sys
    from eventlet.support import greenlets as greenlet

    g_id = id(greenlet.getcurrent())
    if g_id is None:
        if greenlet.getcurrent().parent is None:
            ident = "greenlet-main"
        else:
            g_id = id(greenlet.getcurrent())
            if g_id < 0:
                g_id += 1 + ((sys.maxint + 1) << 1)
            ident = "%08X" % (g_id,)
    else:
        ident = "greenlet-%d" % (g_id,)
    print >>sys.stderr, "[%s] %s" % (ident, " ".join(map(str, args)))
Beispiel #13
0
 def _tasklet_loop(self):
     deque = self.deque = collections.deque()
     hub = api.get_hub()
     current = greenlet.getcurrent()
     def switch(g, value=None, exc=None):
         if exc is None:
             return g.switch(value)
         else:
             return g.throw(exc)
     direction, caller, args = switch(current.parent or current)
     try:
         while True:
             if direction == -1:
                 # waiting to receive
                 if self.balance > 0:
                     sender, args = deque.popleft()
                     hub.schedule_call(0, switch, sender)
                     hub.schedule_call(0, switch, caller, *args)
                 else:
                     deque.append(caller)
             else:
                 # waiting to send
                 if self.balance < 0:
                     receiver = deque.popleft()
                     hub.schedule_call(0, switch, receiver, *args)
                     hub.schedule_call(0, switch, caller)
                 else:
                     deque.append((caller, args))
             self.balance += direction
             direction, caller, args = hub.switch()
     finally:
         deque.clear()
         del self.deque
         self.balance = 0
Beispiel #14
0
    def add(self, evtype, fileno, cb):
        """ Signals an intent to read or write a particular file descriptor.

        The *evtype* argument is either the constant READ or WRITE.

        The *fileno* argument is the file number of the file of interest.

        The *cb* argument is the callback which will be called when the file
        is ready for reading/writing.
        """
        g = greenlet.getcurrent()
        # Update the active list whenever a callback is called
        def _cb(fileno):
            if hasattr(g,'idleness'):
                self.active.add(g)
            cb(fileno)
        listener = self.lclass(evtype, fileno, _cb)
        bucket = self.listeners[evtype]
        if fileno in bucket:
            if g_prevent_multiple_readers:
                raise RuntimeError("Second simultaneous %s on fileno %s "\
                     "detected.  Unless you really know what you're doing, "\
                     "make sure that only one greenthread can %s any "\
                     "particular socket.  Consider using a pools.Pool. "\
                     "If you do know what you're doing and want to disable "\
                     "this error, call "\
                     "eventlet.debug.hub_prevent_multiple_readers(False)" % (
                     evtype, fileno, evtype))
            # store off the second listener in another structure
            self.secondaries[evtype].setdefault(fileno, []).append(listener)
        else:
            bucket[fileno] = listener
        return listener
Beispiel #15
0
 def schedule_call_local(self, seconds, cb, *args, **kwargs):
     current = greenlet.getcurrent()
     if current is self.greenlet:
         return self.schedule_call_global(seconds, cb, *args, **kwargs)
     event_impl = event.event(_scheduled_call_local, (cb, args, kwargs, current))
     wrapper = event_wrapper(event_impl, seconds=seconds)
     self.events_to_add.append(wrapper)
     return wrapper
Beispiel #16
0
def sleep(seconds=0):
    """Yield control to another eligible coroutine until at least *seconds* have
    elapsed.

    *seconds* may be specified as an integer, or a float if fractional seconds
    are desired. Calling :func:`~greenthread.sleep` with *seconds* of 0 is the
    canonical way of expressing a cooperative yield. For example, if one is
    looping over a large list performing an expensive calculation without
    calling any socket methods, it's a good idea to call ``sleep(0)``
    occasionally; otherwise nothing else will run.
    """
    hub = hubs.get_hub()
    assert hub.greenlet is not greenlet.getcurrent(), "do not call blocking functions from the mainloop"
    timer = hub.schedule_call_global(seconds, greenlet.getcurrent().switch)
    try:
        hub.switch()
    finally:
        timer.cancel()
Beispiel #17
0
def sleep(seconds=0):
    """Yield control to another eligible coroutine until at least *seconds* have
    elapsed.

    *seconds* may be specified as an integer, or a float if fractional seconds
    are desired. Calling :func:`~greenthread.sleep` with *seconds* of 0 is the
    canonical way of expressing a cooperative yield. For example, if one is
    looping over a large list performing an expensive calculation without
    calling any socket methods, it's a good idea to call ``sleep(0)``
    occasionally; otherwise nothing else will run.
    """
    hub = hubs.get_hub()
    assert hub.greenlet is not greenlet.getcurrent(
    ), 'do not call blocking functions from the mainloop'
    timer = hub.schedule_call_global(seconds, greenlet.getcurrent().switch)
    try:
        hub.switch()
    finally:
        timer.cancel()
Beispiel #18
0
def g_log(*args):
    warnings.warn("eventlet.util.g_log is deprecated because "
                  "we're pretty sure no one uses it.  "
                  "Send mail to [email protected] "
                  "if you are actually using it.",
        DeprecationWarning, stacklevel=2)
    import sys
    from eventlet.support import greenlets as greenlet
    g_id = id(greenlet.getcurrent())
    if g_id is None:
        if greenlet.getcurrent().parent is None:
            ident = 'greenlet-main'
        else:
            g_id = id(greenlet.getcurrent())
            if g_id < 0:
                g_id += 1 + ((sys.maxint + 1) << 1)
            ident = '%08X' % (g_id,)
    else:
        ident = 'greenlet-%d' % (g_id,)
    print >>sys.stderr, '[%s] %s' % (ident, ' '.join(map(str, args)))
Beispiel #19
0
 def abort(self, wait = False):
     self.stopping = True
     gc.collect()
     aliveGreenlets = self._countManagedGreenlets()
     if aliveGreenlets <= 0:
         QCoreApplication.instance().quit()
     else:
         logger.warning("Wait for %s greenlets to terminate.", aliveGreenlets)
         QTimer.singleShot(1000, self._foreToQuitApplication)
     if wait:
         assert self.greenlet is not greenlet.getcurrent(), \
                 "Can't abort with wait from inside the hub's greenlet."
         self.switch()
Beispiel #20
0
def g_log(*args):
    warnings.warn(
        "eventlet.util.g_log is deprecated because "
        "we're pretty sure no one uses it.  "
        "Send mail to [email protected] "
        "if you are actually using it.",
        DeprecationWarning,
        stacklevel=2)
    import sys
    from eventlet.support import greenlets as greenlet
    g_id = id(greenlet.getcurrent())
    if g_id is None:
        if greenlet.getcurrent().parent is None:
            ident = 'greenlet-main'
        else:
            g_id = id(greenlet.getcurrent())
            if g_id < 0:
                g_id += 1 + ((sys.maxint + 1) << 1)
            ident = '%08X' % (g_id, )
    else:
        ident = 'greenlet-%d' % (g_id, )
    print >> sys.stderr, '[%s] %s' % (ident, ' '.join(map(str, args)))
Beispiel #21
0
    def acquire(self):
        current = greenlet.getcurrent()
        if (self._waiters or self._count > 0) and self._holder is not current:
            # block until lock is free
            self._waiters.append(current)
            self._hub.switch()
            w = self._waiters.popleft()

            assert w is current, 'Waiting threads woken out of order'
            assert self._count == 0, 'After waking a thread, the lock must be unacquired'

        self._holder = current
        self._count += 1
Beispiel #22
0
    def acquire(self):
        current = greenlet.getcurrent()
        if (self._waiters or self._count > 0) and self._holder is not current:
            # block until lock is free
            self._waiters.append(current)
            self._hub.switch()
            w = self._waiters.popleft()

            assert w is current, 'Waiting threads woken out of order'
            assert self._count == 0, 'After waking a thread, the lock must be unacquired'

        self._holder = current
        self._count += 1
def trampoline(fd,
               read=None,
               write=None,
               timeout=None,
               timeout_exc=timeout.Timeout,
               mark_as_closed=None):
    """Suspend the current coroutine until the given socket object or file
    descriptor is ready to *read*, ready to *write*, or the specified
    *timeout* elapses, depending on arguments specified.

    To wait for *fd* to be ready to read, pass *read* ``=True``; ready to
    write, pass *write* ``=True``. To specify a timeout, pass the *timeout*
    argument in seconds.

    If the specified *timeout* elapses before the socket is ready to read or
    write, *timeout_exc* will be raised instead of ``trampoline()``
    returning normally.

    .. note :: |internal|
    """
    t = None
    hub = get_hub()
    current = greenlet.getcurrent()
    assert hub.greenlet is not current, 'do not call blocking functions from the mainloop'
    assert not (read
                and write), 'not allowed to trampoline for reading and writing'
    try:
        fileno = fd.fileno()
    except AttributeError:
        fileno = fd
    if timeout is not None:

        def _timeout(exc):
            # This is only useful to insert debugging
            current.throw(exc)

        t = hub.schedule_call_global(timeout, _timeout, timeout_exc)
    try:
        if read:
            listener = hub.add(hub.READ, fileno, current.switch, current.throw,
                               mark_as_closed)
        elif write:
            listener = hub.add(hub.WRITE, fileno, current.switch,
                               current.throw, mark_as_closed)
        try:
            return hub.switch()
        finally:
            hub.remove(listener)
    finally:
        if t is not None:
            t.cancel()
Beispiel #24
0
 def abort(self, wait=False):
     self.stopping = True
     gc.collect()
     aliveGreenlets = self._countManagedGreenlets()
     if aliveGreenlets <= 0:
         QCoreApplication.instance().quit()
     else:
         logger.warning("Wait for %s greenlets to terminate.",
                        aliveGreenlets)
         QTimer.singleShot(1000, self._foreToQuitApplication)
     if wait:
         assert self.greenlet is not greenlet.getcurrent(), \
             "Can't abort with wait from inside the hub's greenlet."
         self.switch()
Beispiel #25
0
    def block(self):
        if self._blocked_thread is not None:
            raise Exception("Cannot block more than one thread on one BlockedThread")
        self._blocked_thread = greenlet.getcurrent()

        try:
            self._hub.switch()
        finally:
            self._blocked_thread = None
            # cleanup the wakeup task
            if self._wakeupper is not None:
                # Important to cancel the wakeup task so it doesn't
                # spuriously wake this greenthread later on.
                self._wakeupper.cancel()
                self._wakeupper = None
Beispiel #26
0
    def block(self):
        if self._blocked_thread is not None:
            raise Exception("Cannot block more than one thread on one BlockedThread")
        self._blocked_thread = greenlet.getcurrent()

        try:
            self._hub.switch()
        finally:
            self._blocked_thread = None
            # cleanup the wakeup task
            if self._wakeupper is not None:
                # Important to cancel the wakeup task so it doesn't
                # spuriously wake this greenthread later on.
                self._wakeupper.cancel()
                self._wakeupper = None
Beispiel #27
0
 def run(self):
     while True:
         try:
             self.dispatch()
         except greenlet.GreenletExit:
             break
         except self.SYSTEM_EXCEPTIONS:
             raise
         except:
             if self.signal_exc_info is not None:
                 self.schedule_call_global(
                     0, greenlet.getcurrent().parent.throw, *self.signal_exc_info)
                 self.signal_exc_info = None
             else:
                 self.squelch_timer_exception(None, sys.exc_info())
Beispiel #28
0
def select(read_list, write_list, error_list, timeout=None):
    hub = get_hub()
    t = None
    current = greenlet.getcurrent()
    assert hub.greenlet is not current, 'do not call blocking functions from the mainloop'
    ds = {}
    for r in read_list:
        ds[get_fileno(r)] = {'read' : r}
    for w in write_list:
        ds.setdefault(get_fileno(w), {})['write'] = w
    for e in error_list:
        ds.setdefault(get_fileno(e), {})['error'] = e

    descriptors = []

    def on_read(d):
        original = ds[get_fileno(d)]['read']
        current.switch(([original], [], []))

    def on_write(d):
        original = ds[get_fileno(d)]['write']
        current.switch(([], [original], []))

    def on_error(d, _err=None):
        original = ds[get_fileno(d)]['error']
        current.switch(([], [], [original]))

    def on_timeout():
        current.switch(([], [], []))

    if timeout is not None:
        t = hub.schedule_call_global(timeout, on_timeout)
    try:
        for k, v in ds.iteritems():
            d = hub.add_descriptor(k,
                                   v.get('read') is not None and on_read,
                                   v.get('write') is not None and on_write,
                                   v.get('error') is not None and on_error)
            descriptors.append(d)
        try:
            return hub.switch()
        finally:
            for d in descriptors:
                hub.remove_descriptor(d)
    finally:
        if t is not None:
            t.cancel()
Beispiel #29
0
 def switch(self):
     cur = greenlet.getcurrent()
     assert cur is not self.greenlet, 'Cannot switch to MAINLOOP from MAINLOOP'
     switch_out = getattr(cur, 'switch_out', None)
     if switch_out is not None:
         try:
             switch_out()
         except:
             self.squelch_generic_exception(sys.exc_info())
     self.ensure_greenlet()
     try:
         if self.greenlet.parent is not cur:
             cur.parent = self.greenlet
     except ValueError:
         pass  # gets raised if there is a greenlet parent cycle
     clear_sys_exc_info()
     return self.greenlet.switch()
Beispiel #30
0
 def switch(self):
     cur = greenlet.getcurrent()
     assert cur is not self.greenlet, 'Cannot switch to MAINLOOP from MAINLOOP'
     switch_out = getattr(cur, 'switch_out', None)
     if switch_out is not None:
         try:
             switch_out()
         except:
             self.squelch_generic_exception(sys.exc_info())
     self.ensure_greenlet()
     try:
         if self.greenlet.parent is not cur:
             cur.parent = self.greenlet
     except ValueError:
         pass  # gets raised if there is a greenlet parent cycle
     clear_sys_exc_info()
     return self.greenlet.switch()
Beispiel #31
0
    def abort(self, wait=False):
        """Stop the runloop. If run is executing, it will exit after
        completing the next runloop iteration.

        Set *wait* to True to cause abort to switch to the hub immediately and
        wait until it's finished processing.  Waiting for the hub will only
        work from the main greenthread; all other greenthreads will become
        unreachable.
        """
        if self.running:
            self.stopping = True
        if wait:
            assert self.greenlet is not greenlet.getcurrent(), "Can't abort with wait from inside the hub's greenlet."
            # schedule an immediate timer just so the hub doesn't sleep
            self.schedule_call_global(0, lambda: None)
            # switch to it; when done the hub will switch back to its parent,
            # the main greenlet
            self.switch()
Beispiel #32
0
    def abort(self, wait=False):
        """Stop the runloop. If run is executing, it will exit after
        completing the next runloop iteration.

        Set *wait* to True to cause abort to switch to the hub immediately and
        wait until it's finished processing.  Waiting for the hub will only
        work from the main greenthread; all other greenthreads will become
        unreachable.
        """
        if self.running:
            self.stopping = True
        if wait:
            assert self.greenlet is not greenlet.getcurrent(), "Can't abort with wait from inside the hub's greenlet."
            # schedule an immediate timer just so the hub doesn't sleep
            self.schedule_call_global(0, lambda: None)
            # switch to it; when done the hub will switch back to its parent,
            # the main greenlet
            self.switch()
Beispiel #33
0
def current_thread():
    global __patched_enumerate
    g = greenlet.getcurrent()
    if not g:
        # Not currently in a greenthread, fall back to standard function
        return _fixup_thread(__orig_threading.current_thread())

    try:
        active = __threadlocal.active
    except AttributeError:
        active = __threadlocal.active = {}

    g_id = id(g)
    t = active.get(g_id)
    if t is not None:
        return t

    # FIXME: move import from function body to top
    # (jaketesler@github) Furthermore, I was unable to have the current_thread() return correct results from
    # threading.enumerate() unless the enumerate() function was a) imported at runtime using the gross __import__() call
    # and b) was hot-patched using patch_function().
    # https://github.com/eventlet/eventlet/issues/172#issuecomment-379421165
    if __patched_enumerate is None:
        __patched_enumerate = eventlet.patcher.patch_function(
            __import__('threading').enumerate)
    found = [th for th in __patched_enumerate() if th.ident == g_id]
    if found:
        return found[0]

    # Add green thread to active if we can clean it up on exit
    def cleanup(g):
        del active[g_id]

    try:
        g.link(cleanup)
    except AttributeError:
        # Not a GreenThread type, so there's no way to hook into
        # the green thread exiting. Fall back to the standard
        # function then.
        t = _fixup_thread(__orig_threading.current_thread())
    else:
        t = active[g_id] = _GreenThread(g)

    return t
Beispiel #34
0
def trampoline(fd, read=None, write=None, timeout=None,
               timeout_exc=timeout.Timeout,
               mark_as_closed = None):
    """Suspend the current coroutine until the given socket object or file
    descriptor is ready to *read*, ready to *write*, or the specified
    *timeout* elapses, depending on arguments specified.

    To wait for *fd* to be ready to read, pass *read* ``=True``; ready to
    write, pass *write* ``=True``. To specify a timeout, pass the *timeout*
    argument in seconds.

    If the specified *timeout* elapses before the socket is ready to read or
    write, *timeout_exc* will be raised instead of ``trampoline()``
    returning normally.

    .. note :: |internal|
    """
    t = None
    hub = get_hub()
    current = greenlet.getcurrent()
    assert hub.greenlet is not current, 'do not call blocking functions from the mainloop'
    assert not (
        read and write), 'not allowed to trampoline for reading and writing'
    try:
        fileno = fd.fileno()
    except AttributeError:
        fileno = fd
    if timeout is not None:
        def _timeout(exc):
            # This is only useful to insert debugging
            current.throw(exc)
        t = hub.schedule_call_global(timeout, _timeout, timeout_exc)
    try:
        if read:
            listener = hub.add(hub.READ, fileno, current.switch, current.throw, mark_as_closed)
        elif write:
            listener = hub.add(hub.WRITE, fileno, current.switch, current.throw, mark_as_closed)
        try:
            return hub.switch()
        finally:
            hub.remove(listener)
    finally:
        if t is not None:
            t.cancel()
Beispiel #35
0
 def schedule_call_idleness(self, seconds, cb, *args, **kw):
     """Schedule a callable to be called after 'seconds' seconds have
     elapsed. Cancel the timer if greenlet has exited.
         count only idle time - i.e. non active time passing.
         seconds: The number of idle seconds to wait.
         cb: The callable to call after the given time.
         *args: Arguments to pass to the callable when called.
         **kw: Keyword arguments to pass to the callable when called.
     """
     # mark the greenlent to calculate idle time
     g = greenlet.getcurrent()
     g.idleness = 1  # may be extended in the future to counting timers
     t = timer.LocalTimer(seconds, cb, *args, **kw)
     # mark the timer to consider idle time
     t.idleness = True
     # Set the timer to the initial active_clock of the greenlet
     timer.active_clock = g.active_clock
     self.add_timer(t)
     return t
Beispiel #36
0
def trampoline(fd, read=None, write=None, timeout=None, timeout_exc=TimeoutError):
    """Suspend the current coroutine until the given socket object or file
    descriptor is ready to *read*, ready to *write*, or the specified
    *timeout* elapses, depending on arguments specified.

    To wait for *fd* to be ready to read, pass *read* ``=True``; ready to
    write, pass *write* ``=True``. To specify a timeout, pass the *timeout*
    argument in seconds.

    If the specified *timeout* elapses before the socket is ready to read or
    write, *timeout_exc* will be raised instead of ``trampoline()``
    returning normally.
    """
    t = None
    hub = get_hub()
    current = greenlet.getcurrent()
    assert hub.greenlet is not current, 'do not call blocking functions from the mainloop'
    fileno = getattr(fd, 'fileno', lambda: fd)()
    def _do_close(_d, error=None):
        if error is None:
            current.throw(socket.error(32, 'Broken pipe'))
        else:
            current.throw(getattr(error, 'value', error)) # XXX convert to socket.error
    def cb(d):
        current.switch()
        # with TwistedHub, descriptor is actually an object (socket_rwdescriptor) which stores
        # this callback. If this callback stores a reference to the socket instance (fd)
        # then descriptor has a reference to that instance. This makes socket not collected
        # after greenlet exit. Since nobody actually uses the results of this switch, I removed
        # fd from here. If it will be needed than an indirect reference which is discarded right
        # after the switch above should be used.
    if timeout is not None:
        t = hub.schedule_call_global(timeout, current.throw, timeout_exc)
    try:
        descriptor = hub.add_descriptor(fileno, read and cb, write and cb, _do_close)
        try:
            return hub.switch()
        finally:
            hub.remove_descriptor(descriptor)
    finally:
        if t is not None:
            t.cancel()
Beispiel #37
0
 def switch(self):
     cur = greenlet.getcurrent()
     assert cur is not self.greenlet, "Cannot switch to MAINLOOP from MAINLOOP"
     switch_out = getattr(cur, "switch_out", None)
     if switch_out is not None:
         try:
             switch_out()
         except:
             self.squelch_generic_exception(sys.exc_info())
             clear_sys_exc_info()
     if self.greenlet.dead:
         self.greenlet = greenlet.greenlet(self.run)
     try:
         if self.greenlet.parent is not cur:
             cur.parent = self.greenlet
     except ValueError:
         pass  # gets raised if there is a greenlet parent cycle
     del cur, switch_out
     clear_sys_exc_info()
     return self.greenlet.switch()
Beispiel #38
0
    def wait(self, timeout=None):
        """Wait until another coroutine calls :meth:`send`.
        Returns the value the other coroutine passed to :meth:`send`.

        >>> import eventlet
        >>> evt = eventlet.Event()
        >>> def wait_on():
        ...    retval = evt.wait()
        ...    print("waited for {0}".format(retval))
        >>> _ = eventlet.spawn(wait_on)
        >>> evt.send('result')
        >>> eventlet.sleep(0)
        waited for result

        Returns immediately if the event has already occurred.

        >>> evt.wait()
        'result'

        When the timeout argument is present and not None, it should be a floating point number
        specifying a timeout for the operation in seconds (or fractions thereof).
        """
        current = greenlet.getcurrent()
        if self._result is NOT_USED:
            hub = hubs.get_hub()
            self._waiters.add(current)
            timer = None
            if timeout is not None:
                timer = hub.schedule_call_local(timeout, self._do_send, None,
                                                None, current)
            try:
                result = hub.switch()
                if timer is not None:
                    timer.cancel()
                return result
            finally:
                self._waiters.discard(current)
        if self._exc is not None:
            current.throw(*self._exc)
        return self._result
Beispiel #39
0
 def __init__(self, evtype, fileno, cb, tb, mark_as_closed):
     """ The following are required:
     cb - the standard callback, which will switch into the
         listening greenlet to indicate that the event waited upon
         is ready
     tb - a 'throwback'. This is typically greenlet.throw, used
         to raise a signal into the target greenlet indicating that
         an event was obsoleted by its underlying filehandle being
         repurposed.
     mark_as_closed - if any listener is obsoleted, this is called
         (in the context of some other client greenlet) to alert
         underlying filehandle-wrapping objects that they've been
         closed.
     """
     assert (evtype is READ or evtype is WRITE)
     self.evtype = evtype
     self.fileno = fileno
     self.cb = cb
     self.tb = tb
     self.mark_as_closed = mark_as_closed
     self.spent = False
     self.greenlet = greenlet.getcurrent()
Beispiel #40
0
 def __init__(self, evtype, fileno, cb, tb, mark_as_closed):
     """ The following are required:
     cb - the standard callback, which will switch into the
         listening greenlet to indicate that the event waited upon
         is ready
     tb - a 'throwback'. This is typically greenlet.throw, used
         to raise a signal into the target greenlet indicating that
         an event was obsoleted by its underlying filehandle being
         repurposed.
     mark_as_closed - if any listener is obsoleted, this is called
         (in the context of some other client greenlet) to alert
         underlying filehandle-wrapping objects that they've been
         closed.
     """
     assert (evtype is READ or evtype is WRITE)
     self.evtype = evtype
     self.fileno = fileno
     self.cb = cb
     self.tb = tb
     self.mark_as_closed = mark_as_closed
     self.spent = False
     self.greenlet = greenlet.getcurrent()
Beispiel #41
0
    def wait(self, timeout=None):
        """Wait until another coroutine calls :meth:`send`.
        Returns the value the other coroutine passed to :meth:`send`.

        >>> import eventlet
        >>> evt = eventlet.Event()
        >>> def wait_on():
        ...    retval = evt.wait()
        ...    print("waited for {0}".format(retval))
        >>> _ = eventlet.spawn(wait_on)
        >>> evt.send('result')
        >>> eventlet.sleep(0)
        waited for result

        Returns immediately if the event has already occurred.

        >>> evt.wait()
        'result'

        When the timeout argument is present and not None, it should be a floating point number
        specifying a timeout for the operation in seconds (or fractions thereof).
        """
        current = greenlet.getcurrent()
        if self._result is NOT_USED:
            hub = hubs.get_hub()
            self._waiters.add(current)
            timer = None
            if timeout is not None:
                timer = hub.schedule_call_local(timeout, self._do_send, None, None, current)
            try:
                result = hub.switch()
                if timer is not None:
                    timer.cancel()
                return result
            finally:
                self._waiters.discard(current)
        if self._exc is not None:
            current.throw(*self._exc)
        return self._result
Beispiel #42
0
def get_ident(gr=None):
    if gr is None:
        return id(greenlet.getcurrent())
    else:
        return id(gr)
Beispiel #43
0
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

"""Integrate eventlet with twisted's reactor mainloop.

You generally don't have to use it unless you need to call reactor.run()
yourself.
"""
from eventlet.hubs.twistedr import BaseTwistedHub
from eventlet.api import use_hub, _threadlocal
from eventlet.support import greenlets as greenlet

use_hub(BaseTwistedHub)
assert not hasattr(_threadlocal, 'hub')
hub = _threadlocal.hub = _threadlocal.Hub(greenlet.getcurrent())

Beispiel #44
0
 def __init__(self, *args, **kwargs):
     self.greenlet = greenlet.getcurrent()
     DelayedCall.__init__(self, *args, **kwargs)
Beispiel #45
0
def get_ident(gr=None):
    if gr is None:
        return id(greenlet.getcurrent())
    else:
        return id(gr)
Beispiel #46
0
def interrupt_main():
    curr = greenlet.getcurrent()
    if curr.parent and not curr.parent.dead:
        curr.parent.throw(KeyboardInterrupt())
    else:
        raise KeyboardInterrupt()
Beispiel #47
0
 def abort(self, wait=True):
     self.schedule_call_global(0, self.greenlet.throw, greenlet.GreenletExit)
     if wait:
         assert self.greenlet is not greenlet.getcurrent(), "Can't abort with wait from inside the hub's greenlet."
         self.switch()
Beispiel #48
0
 def __init__(self, evtype, fileno, cb):
     self.where_called = traceback.format_stack()
     self.greenlet = greenlet.getcurrent()
     super(DebugListener, self).__init__(evtype, fileno, cb)
Beispiel #49
0
 def stop(self):
     self.abort()
     if self.greenlet is not greenlet.getcurrent():
         self.switch()
Beispiel #50
0
def interrupt_main():
    curr = greenlet.getcurrent()
    if curr.parent and not curr.parent.dead:
        curr.parent.throw(KeyboardInterrupt())
    else:
        raise KeyboardInterrupt()
Beispiel #51
0
 def __init__(self, *args, **kwargs):
     self.greenlet = greenlet.getcurrent()
     Timer.__init__(self, *args, **kwargs)
Beispiel #52
0
"""Integrate eventlet with twisted's reactor mainloop.

You generally don't have to use it unless you need to call reactor.run()
yourself.
"""
from eventlet.hubs.twistedr import BaseTwistedHub
from eventlet.support import greenlets as greenlet
from eventlet.hubs import _threadlocal, use_hub

use_hub(BaseTwistedHub)
assert not hasattr(_threadlocal, 'hub')
hub = _threadlocal.hub = _threadlocal.Hub(greenlet.getcurrent())
Beispiel #53
0
 def __init__(self, evtype, fileno, cb, tb, mark_as_closed):
     self.where_called = traceback.format_stack()
     self.greenlet = greenlet.getcurrent()
     super(DebugListener, self).__init__(evtype, fileno, cb, tb,
                                         mark_as_closed)