Example #1
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
Example #2
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
Example #3
0
def get(url):
    hub = evy.hubs.get_hub()
    c = pycurl_orig.Curl()
    c.setopt(pycurl_orig.URL, url)

    c.setopt(pycurl_orig.NOSIGNAL, 1)
    THE_MULTI.add_handle(c)

    hub.add_observer(runloop_observer, 'before_waiting')

    while True:
        print "TOP"
        result, numhandles = THE_MULTI.socket_all()
        print "PERFORM RESULT", result
        while result == pycurl_orig.E_CALL_MULTI_PERFORM:
            result, numhandles = THE_MULTI.socket_all()
            print "PERFORM RESULT2", result

        if LAST_SOCKET_DONE:
            break

        SUSPENDED_COROS[LAST_SOCKET] = greenlet.getcurrent()
        print "SUSPENDED", SUSPENDED_COROS
        evy.hubs.get_hub().switch()
        print "BOTTOM"

    if not SUSPENDED_COROS:
        hub.remove_observer(runloop_observer)
Example #4
0
def get(url):
    hub = evy.hubs.get_hub()
    c = pycurl_orig.Curl()
    c.setopt(pycurl_orig.URL, url)

    c.setopt(pycurl_orig.NOSIGNAL, 1)
    THE_MULTI.add_handle(c)

    hub.add_observer(runloop_observer, 'before_waiting')

    while True:
        print "TOP"
        result, numhandles = THE_MULTI.socket_all()
        print "PERFORM RESULT", result
        while result == pycurl_orig.E_CALL_MULTI_PERFORM:
            result, numhandles = THE_MULTI.socket_all()
            print "PERFORM RESULT2", result

        if LAST_SOCKET_DONE:
            break

        SUSPENDED_COROS[LAST_SOCKET] = greenlet.getcurrent()
        print "SUSPENDED", SUSPENDED_COROS
        evy.hubs.get_hub().switch()
        print "BOTTOM"

    if not SUSPENDED_COROS:
        hub.remove_observer(runloop_observer)
Example #5
0
File: hub.py Project: PlumpMath/evy
 def cede(self):
     """
     Switch temporarily to any other greenlet, and then return to the current greenlet
     :return: the greenlet that takes control
     """
     current = greenlet.getcurrent()
     self.run_callback(current.switch)
     return self.switch()
Example #6
0
File: hub.py Project: inercia/evy
 def cede(self):
     """
     Switch temporarily to any other greenlet, and then return to the current greenlet
     :return: the greenlet that takes control
     """
     current = greenlet.getcurrent()
     self.run_callback(current.switch)
     return self.switch()
Example #7
0
File: zmq.py Project: inercia/evy
    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
Example #8
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
Example #9
0
File: zmq.py Project: inercia/evy
    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
Example #10
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
Example #11
0
File: hub.py Project: inercia/evy
    def abort (self, wait = False):
        """
        Stop the loop. If run is executing, it will exit after completing the next loop 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.run_callback(lambda: None)
            # switch to it; when done the hub will switch back to its parent,
            # the main greenlet
            self.switch()
Example #12
0
File: hub.py Project: PlumpMath/evy
    def abort(self, wait=False):
        """
        Stop the loop. If run is executing, it will exit after completing the next loop 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.run_callback(lambda: None)
            # switch to it; when done the hub will switch back to its parent,
            # the main greenlet
            self.switch()
Example #13
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:
            self.timer = None       # "fake" timeout (never expires)
        else:
            hub = get_hub()
            if self.exception is None or isinstance(self.exception, bool): # timeout that raises self
                exc = self
            else: # regular timeout with user-provided exception
                exc = self.exception

            self.timer = hub.schedule_call_global(self.seconds, greenlet.getcurrent().throw, exc)
            self.timer.forget()     ## forget about the timer, so we do not keep the loop alive...

        return self
Example #14
0
def trampoline(fd, read=None, write=None, timeout=None, timeout_exc=Timeout):
    """
    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:
        t = hub.schedule_call_global(timeout, current.throw, timeout_exc)

    try:
        if read: listener = hub.add(hub.READ, fileno, current.switch)
        elif write: listener = hub.add(hub.WRITE, fileno, current.switch)

        try:
            return hub.switch()
        finally:
            hub.remove(listener)
    finally:
        if t is not None:
            t.cancel()
Example #15
0
File: hub.py Project: inercia/evy
 def switch (self):
     """
     Switches to a different greenlet
     :return:
     :rtype:
     """
     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()
Example #16
0
def trampoline (fd, read = None, write = None, timeout = None, timeout_exc = Timeout):
    """
    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:
        t = hub.schedule_call_global(timeout, current.throw, timeout_exc)

    try:
        if read:        listener = hub.add(hub.READ,  fileno, current.switch)
        elif write:     listener = hub.add(hub.WRITE, fileno, current.switch)

        try:
            return hub.switch()
        finally:
            hub.remove(listener)
    finally:
        if t is not None:
            t.cancel()
Example #17
0
File: hub.py Project: PlumpMath/evy
 def switch(self):
     """
     Switches to a different greenlet
     :return:
     :rtype:
     """
     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()
Example #18
0
File: event.py Project: inercia/evy
    def wait (self, timeout = None, exception = None):
        """
        Wait until another coroutine calls :meth:`send`.
        Returns the value the other coroutine passed to
        :meth:`send`.

        >>> from evy import event
        >>> import evy
        >>> evt = event.Event()
        >>> def wait_on():
        ...    retval = evt.wait()
        ...    print "waited for", retval
        >>> _ = evy.spawn(wait_on)
        >>> evt.send('result')
        >>> 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:
            with Timeout(timeout, exception):
                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
Example #19
0
    def wait(self, timeout=None, exception=None):
        """
        Wait until another coroutine calls :meth:`send`.
        Returns the value the other coroutine passed to
        :meth:`send`.

        >>> from evy import event
        >>> import evy
        >>> evt = event.Event()
        >>> def wait_on():
        ...    retval = evt.wait()
        ...    print "waited for", retval
        >>> _ = evy.spawn(wait_on)
        >>> evt.send('result')
        >>> 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:
            with Timeout(timeout, exception):
                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
Example #20
0
def get_ident (gr = None):
    if gr is None:
        return id(greenlet.getcurrent())
    else:
        return id(gr)
Example #21
0
 def __init__(self, *args, **kwargs):
     self.greenlet = greenlet.getcurrent()
     Timer.__init__(self, *args, **kwargs)
Example #22
0
def interrupt_main ():
    curr = greenlet.getcurrent()
    if curr.parent and not curr.parent.dead:
        curr.parent.throw(KeyboardInterrupt())
    else:
        raise KeyboardInterrupt()
Example #23
0
File: timer.py Project: inercia/evy
 def __init__(self, *args, **kwargs):
     self.greenlet = greenlet.getcurrent()
     Timer.__init__(self, *args, **kwargs)