Example #1
0
 def handle(self, conn, address):
     f = getcurrent()._fileobj = _fileobject(conn)
     f.stderr = self.stderr
     getcurrent().switch_in()
     try:
         console = InteractiveConsole(self.locals)
         # __builtins__ may either be the __builtin__ module or
         # __builtin__.__dict__ in the latter case typing
         # locals() at the backdoor prompt spews out lots of
         # useless stuff
         try:
             import __builtin__
             console.locals["__builtins__"] = __builtin__
         except ImportError:
             import builtins
             console.locals["builtins"] = builtins
         console.interact(banner=self.banner)
     except SystemExit:  # raised by quit()
         if not PY3:
             sys.exc_clear()
     finally:
         conn.close()
         f.close()
         if PYPY:
             # The underlying socket somewhere has a reference
             # that's not getting closed until finalizers run.
             # Without running them, test__backdoor.Test.test_sys_exit
             # hangs forever
             gc.collect()
Example #2
0
    def _notify_links(self):
        # Subclasses CANNOT override. This is a cdef method.

        # We release self._notifier here. We are called by it
        # at the end of the loop, and it is now false in a boolean way (as soon
        # as this method returns).
        # If we get acquired/released again, we will create a new one, but there's
        # no need to keep it around until that point (making it potentially climb
        # into older GC generations, notably on PyPy)
        notifier = self._notifier
        try:
            while True:
                self._dirty = False
                if not self._links:
                    # In case we were manually unlinked before
                    # the callback. Which shouldn't happen
                    return
                for link in self._links:
                    if self.counter <= 0:
                        return
                    try:
                        link(self) # Must use Cython >= 0.23.4 on PyPy else this leaks memory
                    except:
                        getcurrent().handle_error((link, self), *sys.exc_info())
                    if self._dirty:
                        # We mutated self._links so we need to start over
                        break
                if not self._dirty:
                    return
        finally:
            # We should not have created a new notifier even if callbacks
            # released us because we loop through *all* of our links on the
            # same callback while self._notifier is still true.
            assert self._notifier is notifier
            self._notifier = None
Example #3
0
    def handle(self, conn, _address): # pylint: disable=method-hidden
        """
        Interact with one remote user.

        .. versionchanged:: 1.1b2 Each connection gets its own
            ``locals`` dictionary. Previously they were shared in a
            potentially unsafe manner.
        """
        fobj = conn.makefile(mode="rw")
        fobj = _fileobject(conn, fobj, self.stderr)
        getcurrent()._fileobj = fobj

        getcurrent().switch_in()
        try:
            console = InteractiveConsole(self._create_interactive_locals())
            if sys.version_info[:3] >= (3, 6, 0):
                # Beginning in 3.6, the console likes to print "now exiting <class>"
                # but probably our socket is already closed, so this just causes problems.
                console.interact(banner=self.banner, exitmsg='') # pylint:disable=unexpected-keyword-arg
            else:
                console.interact(banner=self.banner)
        except SystemExit:  # raised by quit()
            if hasattr(sys, 'exc_clear'): # py2
                sys.exc_clear()
        finally:
            conn.close()
            fobj.close()
Example #4
0
 def test_subscribe():
     e = Observer()
     print '000',getcurrent()
     getcurrent().in_another_greenlet = in_another_greenlet
     b = e.subscribe('kill',getcurrent().in_another_greenlet)
     gevent.sleep(5)
     print 'END'
     b.unsubscribe()
Example #5
0
 def run_subscribe(self):
     e = Observer()
     getcurrent().in_another_greenlet = self.in_another_greenlet
     getcurrent().in_another_greenlet2 = self.in_another_greenlet2
     b = e.subscribe('kill',getcurrent().in_another_greenlet)
     c = e.subscribe('kill',getcurrent().in_another_greenlet2)
     gevent.sleep(1)
     b.unsubscribe()
     c.unsubscribe()
Example #6
0
 def start(self):
     """Schedule the timeout."""
     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 = core.timer(self.seconds, getcurrent().throw, self)
     else:  # regular timeout with user-provided exception
         self.timer = core.timer(self.seconds, getcurrent().throw, self.exception)
Example #7
0
 def start(self):
     """Schedule the timeout."""
     assert not self.pending, "%r is already started; to restart it, cancel it first" % self
     if self.seconds is None:  # "fake" timeout (never expires)
         pass
     elif self.exception is None or self.exception is False or isinstance(self.exception, string_types):
         # timeout that raises self
         self.timer.start(getcurrent().throw, self)
     else:  # regular timeout with user-provided exception
         self.timer.start(getcurrent().throw, self.exception)
Example #8
0
 def acquire(self, blocking=True):
     if not blocking and self.locked():
         return False
     if self.counter <= 0:
         self._waiters.add(getcurrent())
         try:
             while self.counter <= 0:
                 get_hub().switch()
         finally:
             self._waiters.discard(getcurrent())
     self.counter -= 1
     return True
Example #9
0
 def _notify_links(self):
     while True:
         self._dirty = False
         for link in self._links:
             if self.counter <= 0:
                 return
             try:
                 link(self)
             except:
                 getcurrent().handle_error((link, self), *sys.exc_info())
             if self._dirty:
                 break
         if not self._dirty:
             return
Example #10
0
    def __init__(self): # pylint:disable=super-init-not-called
        #_DummyThread_.__init__(self)

        # It'd be nice to use a pattern like "greenlet-%d", but maybe somebody out
        # there is checking thread names...
        self._name = self._Thread__name = __threading__._newname("DummyThread-%d")
        # All dummy threads in the same native thread share the same ident
        # (that of the native thread)
        self._set_ident()

        g = getcurrent()
        gid = _get_ident(g)
        __threading__._active[gid] = self
        rawlink = getattr(g, 'rawlink', None)
        if rawlink is not None:
            # raw greenlet.greenlet greenlets don't
            # have rawlink...
            rawlink(_cleanup)
        else:
            # ... so for them we use weakrefs.
            # See https://github.com/gevent/gevent/issues/918
            global _weakref
            if _weakref is None:
                _weakref = __import__('weakref')
            ref = _weakref.ref(g, _make_cleanup_id(gid))
            self.__raw_ref = ref
Example #11
0
 def join(self, timeout=None):
     """Wait until the greenlet finishes or *timeout* expires.
     Return ``None`` regardless.
     """
     if self.ready():
         return
     else:
         switch = getcurrent().switch
         self.rawlink(switch)
         try:
             t = Timeout.start_new(timeout)
             try:
                 result = self.parent.switch()
                 assert result is self, 'Invalid switch into Greenlet.join(): %r' % (result, )
             finally:
                 t.cancel()
         except Timeout as ex:
             self.unlink(switch)
             if ex is not t:
                 raise
             if PY3:
                 ex.__traceback__ = None
         except:
             self.unlink(switch)
             raise
Example #12
0
    def link(self, receiver=None, GreenletLink=GreenletLink, SpawnedLink=SpawnedLink):
        """Link greenlet's completion to callable or another greenlet.

        If *receiver* is a callable then it will be called with this instance as an argument
        once this greenlet's dead. A callable is called in its own greenlet.

        If *receiver* is a greenlet then an :class:`LinkedExited` exception will be
        raised in it once this greenlet's dead.

        If *receiver* is ``None``, link to the current greenlet.

        Always asynchronous, unless receiver is a current greenlet and the result is ready.
        If this greenlet is already dead, then notification will performed in this loop
        iteration as soon as this greenlet switches to the hub.
        """
        current = getcurrent()
        if receiver is None or receiver is current:
            receiver = GreenletLink(current)
            if self.ready():
                # special case : linking to current greenlet when the result is ready
                # raise LinkedExited immediatelly
                receiver(self)
                return
        elif not callable(receiver):
            if isinstance(receiver, greenlet):
                receiver = GreenletLink(receiver)
            else:
                raise TypeError('Expected callable or greenlet: %r' % (receiver, ))
        else:
            receiver = SpawnedLink(receiver)
        self.rawlink(receiver)
Example #13
0
def wait_readwrite(fileno, timeout=-1, timeout_exc=_socket.timeout('timed out')):
    evt = core.readwrite_event(fileno, _wait_helper, timeout, (getcurrent(), timeout_exc))
    try:
        switch_result = get_hub().switch()
        assert evt is switch_result, 'Invalid switch into wait_readwrite(): %r' % (switch_result, )
    finally:
        evt.cancel()
Example #14
0
    def wait(self, timeout=None):
        """Block until the instance is ready.

        If this instance already holds a value / an exception, return immediatelly.
        Otherwise, block until another thread calls :meth:`set` or :meth:`set_exception` or
        until the optional timeout occurs.

        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).

        This method always returns ``None`` regardless of the reason it returns.
        To find out out what happened, use :meth:`ready` and :meth:`successful` methods
        or :attr:`value` and :attr:`exception` properties.
        """
        if self._exception is not _NONE:
            return
        else:
            switch = getcurrent().switch
            self.rawlink(switch)
            try:
                timer = Timeout.start_new(timeout)
                try:
                    result = get_hub().switch()
                    assert result is self, 'Invalid switch into AsyncResult.wait(): %r' % (result, )
                finally:
                    timer.cancel()
            except Timeout, exc:
                self.unlink(switch)
                if exc is not timer:
                    raise
            except:
Example #15
0
 def _do_wait(self, timeout):
     """
     Wait for up to *timeout* seconds to expire. If timeout
     elapses, return the exception. Otherwise, return None.
     Raises timeout if a different timer expires.
     """
     switch = getcurrent().switch
     self.rawlink(switch)
     try:
         # As a tiny efficiency optimization, avoid allocating a timer
         # if not needed.
         timer = Timeout.start_new(timeout) if timeout is not None else None
         try:
             try:
                 result = get_hub().switch()
                 assert result is self, 'Invalid switch into Semaphore.wait/acquire(): %r' % (result, )
             except Timeout as ex:
                 if ex is not timer:
                     raise
                 return ex
         finally:
             if timer is not None:
                 timer.cancel()
     finally:
         self.unlink(switch)
def wait_write(fileno, timeout=-1):
    evt = write_event(fileno, _wait_helper, timeout, getcurrent())
    try:
        switch_result = get_hub().switch()
        assert evt is switch_result, 'Invalid switch into wait_write(): %r' % (switch_result, )
    finally:
        evt.cancel()
Example #17
0
    def get(self, block=True, timeout=None):
        """Return the stored value or raise the exception.

        If this instance already holds a value / an exception, return / raise it immediatelly.
        Otherwise, block until another greenlet calls :meth:`set` or :meth:`set_exception` or
        until the optional timeout occurs.

        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).
        """
        if self._exception is not _NONE:
            if self._exception is None:
                return self.value
            raise self._exception
        elif block:
            switch = getcurrent().switch
            self.rawlink(switch)
            try:
                timer = Timeout.start_new(timeout)
                try:
                    result = self.hub.switch()
                    assert result is self, 'Invalid switch into AsyncResult.get(): %r' % (result, )
                finally:
                    timer.cancel()
            except:
                self.unlink(switch)
                raise
            if self._exception is None:
                return self.value
            raise self._exception
        else:
            raise Timeout
Example #18
0
    def wait(self, timeout=None):
        """Block until the internal flag is true.
        If the internal flag is true on entry, return immediately. Otherwise,
        block until another thread calls :meth:`set` to set the flag to true,
        or until the optional timeout occurs.

        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).

        Return the value of the internal flag (``True`` or ``False``).
        """
        if self._flag:
            return self._flag
        else:
            switch = getcurrent().switch
            self.rawlink(switch)
            try:
                timer = Timeout.start_new(timeout)
                try:
                    try:
                        result = self.hub.switch()
                        assert result is self, 'Invalid switch into Event.wait(): %r' % (result, )
                    except Timeout as ex:
                        if ex is not timer:
                            raise
                finally:
                    timer.cancel()
            finally:
                self.unlink(switch)
        return self._flag
Example #19
0
    def __get_or_peek(self, method, block, timeout):
        # Internal helper method. The `method` should be either
        # self._get when called from self.get() or self._peek when
        # called from self.peek(). Call this after the initial check
        # to see if there are items in the queue.

        if self.hub is getcurrent():
            # special case to make get_nowait() or peek_nowait() runnable in the mainloop greenlet
            # there are no items in the queue; try to fix the situation by unlocking putters
            while self.putters:
                # Note: get() used popleft(), peek used pop(); popleft
                # is almost certainly correct.
                self.putters.popleft().put_and_switch()
                if self.qsize():
                    return method()
            raise Empty()

        if not block:
            # We can't block, we're not the hub, and we have nothing
            # to return. No choice...
            raise Empty()

        waiter = Waiter()
        timeout = Timeout._start_new_or_dummy(timeout, Empty)
        try:
            self.getters.append(waiter)
            if self.putters:
                self._schedule_unlock()
            result = waiter.get()
            if result is not waiter:
                raise InvalidSwitchError('Invalid switch into Queue.get: %r' % (result, ))
            return method()
        finally:
            timeout.cancel()
            _safe_remove(self.getters, waiter)
Example #20
0
    def put(self, item, block=True, timeout=None):
        if self.hub is getcurrent():
            if self.getters:
                getter = self.getters.popleft()
                getter.switch(item)
                return
            raise Full

        if not block:
            timeout = 0

        waiter = Waiter()
        item = (item, waiter)
        self.putters.append(item)
        timeout = Timeout._start_new_or_dummy(timeout, Full)
        try:
            if self.getters:
                self._schedule_unlock()
            result = waiter.get()
            if result is not waiter:
                raise InvalidSwitchError("Invalid switch into Channel.put: %r" % (result, ))
        except:
            _safe_remove(self.putters, item)
            raise
        finally:
            timeout.cancel()
Example #21
0
    def get_socket(self, host, port):
        pid = os.getpid()
        if pid != self._pid:
            self._bootstrap(pid)

        greenlet = getcurrent()
        from_pool = True
        sock = self._used.get(greenlet)
        if sock is None:
            with self._lock:
                if self._count < self.pool_size:
                    self._count += 1
                    from_pool = False
                    sock = self.connect(host, port)
        if sock is None:
            from_pool = True
            sock = self._queue.get(timeout=self.network_timeout)

        if isinstance(greenlet, gevent.Greenlet):
            greenlet.link(self._return)
            self._used[greenlet] = sock
        else:
            ref = weakref.ref(greenlet, self._return)
            self._used[ref] = sock
        return sock, from_pool
Example #22
0
 def release(self):
     if self._owner is not getcurrent():
         raise RuntimeError("cannot release un-aquired lock")
     self._count = count = self._count - 1
     if not count:
         self._owner = None
         self._block.release()
Example #23
0
 def peek(self, block=True, timeout=None):
     if self.qsize():
         if self.putters:
             self._schedule_unlock()
         return self._peek()
     elif not block and get_hub() is getcurrent():
         # special case to make peek(False) runnable in the mainloop
         # greenlet there are no items in the queue; try to fix the
         # situation by unlocking putters
         while self.putters:
             putter = self.putters.pop()
             if putter:
                 putter.switch(putter)
                 if self.qsize():
                     return self._peek()
         raise Empty
     elif block:
         waiter = Waiter()
         timeout = Timeout.start_new(timeout, Empty)
         try:
             self.getters.add(waiter)
             if self.putters:
                 self._schedule_unlock()
             result = waiter.get()
             assert result is waiter, "Invalid switch into Queue.put: %r" % (result,)
             return self._peek()
         finally:
             self.getters.discard(waiter)
             timeout.cancel()
     else:
         raise Empty
Example #24
0
File: lock.py Project: yalon/gevent
    def acquire(self, blocking=1):
        tid = get_ident()
        gid = id(getcurrent())
        tid_gid = (tid, gid)
        if tid_gid == self._owner:  # We trust the GIL here so we can do this comparison w/o locking.
            self._count = self._count + 1
            return True

        greenlet_lock = self._get_greenlet_lock()

        self._wait_queue.append(gid)
        # this is a safety in case an exception is raised somewhere and we must make sure we're not in the queue
        # otherwise it'll get stuck forever.
        remove_from_queue_on_return = True
        try:
            while True:
                if not greenlet_lock.acquire(blocking):
                    return False  # non-blocking and failed to acquire lock

                if self._wait_queue[0] == gid:
                    # Hurray, we can have the lock.
                    self._owner = tid_gid
                    self._count = 1
                    remove_from_queue_on_return = False  # don't remove us from the queue
                    return True
                else:
                    # we already hold the greenlet lock so obviously the owner is not in our thread.
                    greenlet_lock.release()
                    if blocking:
                        sleep(0.0005)  # 500 us -> initial delay of 1 ms
                    else:
                        return False
        finally:
            if remove_from_queue_on_return:
                self._wait_queue.remove(gid)
Example #25
0
    def wait(self, timeout=None):
        """Block until the instance is ready.

        If this instance already holds a value / an exception, return immediatelly.
        Otherwise, block until another thread calls :meth:`set` or :meth:`set_exception` or
        until the optional timeout occurs.

        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).

        Return :attr:`value`.
        """
        if self._exception is not _NONE:
            return self.value
        else:
            switch = getcurrent().switch
            self.rawlink(switch)
            try:
                timer = Timeout.start_new(timeout)
                try:
                    result = self.hub.switch()
                    assert result is self, 'Invalid switch into AsyncResult.wait(): %r' % (result, )
                finally:
                    timer.cancel()
            except Timeout as exc:
                self.unlink(switch)
                if exc is not timer:
                    raise
            except:
                self.unlink(switch)
                raise
            # not calling unlink() in non-exception case, because if switch()
            # finished normally, link was already removed in _notify_links
        return self.value
Example #26
0
    def put(self, item, block=True, timeout=None):
        if self.hub is getcurrent():
            if self.getters:
                getter = self.getters.popleft()
                getter.switch(item)
                return
            raise Full

        if not block:
            timeout = 0

        waiter = Waiter()
        item = (item, waiter)
        self.putters.append(item)
        timeout = Timeout.start_new(timeout, Full)
        try:
            if self.getters:
                self._schedule_unlock()
            result = waiter.get()
            assert result is waiter, "Invalid switch into Channel.put: %r" % (result, )
        except:
            self._discard(item)
            raise
        finally:
            timeout.cancel()
Example #27
0
File: coros.py Project: HVF/gevent
 def acquire(self, blocking=True, timeout=None):
     if self.counter > 0:
         self.counter -= 1
         return True
     elif not blocking:
         return False
     else:
         switch = getcurrent().switch
         self.rawlink(switch)
         try:
             timer = Timeout.start_new(timeout)
             try:
                 try:
                     result = self.hub.switch()
                     assert result is self, "Invalid switch into Semaphore.acquire(): %r" % (result,)
                 except Timeout:
                     ex = sys.exc_info()[1]
                     if ex is timer:
                         return False
                     raise
             finally:
                 timer.cancel()
         finally:
             self.unlink(switch)
         self.counter -= 1
         assert self.counter >= 0
         return True
Example #28
0
    def peek(self, block=True, timeout=None):
        """Return an item from the queue without removing it.

        If optional args *block* is true and *timeout* is ``None`` (the default),
        block if necessary until an item is available. If *timeout* is a positive number,
        it blocks at most *timeout* seconds and raises the :class:`Empty` exception
        if no item was available within that time. Otherwise (*block* is false), return
        an item if one is immediately available, else raise the :class:`Empty` exception
        (*timeout* is ignored in that case).
        """
        if self.qsize():
            return self._peek()
        elif self.hub is getcurrent():
            # special case to make peek(False) runnable in the mainloop greenlet
            # there are no items in the queue; try to fix the situation by unlocking putters
            while self.putters:
                self.putters.pop().put_and_switch()
                if self.qsize():
                    return self._peek()
            raise Empty
        elif block:
            waiter = Waiter()
            timeout = Timeout.start_new(timeout, Empty)
            try:
                self.getters.add(waiter)
                if self.putters:
                    self._schedule_unlock()
                result = waiter.get()
                assert result is waiter, 'Invalid switch into Queue.peek: %r' % (result, )
                return self._peek()
            finally:
                self.getters.discard(waiter)
                timeout.cancel()
        else:
            raise Empty
Example #29
0
 def _wait_core(self, timeout, catch=Timeout):
     # The core of the wait implementation, handling
     # switching and linking. If *catch* is set to (),
     # a timeout that elapses will be allowed to be raised.
     # Returns a true value if the wait succeeded without timing out.
     switch = getcurrent().switch
     self.rawlink(switch)
     try:
         timer = Timeout._start_new_or_dummy(timeout)
         try:
             try:
                 result = self.hub.switch()
                 if result is not self: # pragma: no cover
                     raise InvalidSwitchError('Invalid switch into Event.wait(): %r' % (result, ))
                 return True
             except catch as ex:
                 if ex is not timer:
                     raise
                 # test_set_and_clear and test_timeout in test_threading
                 # rely on the exact return values, not just truthish-ness
                 return False
         finally:
             timer.cancel()
     finally:
         self.unlink(switch)
Example #30
0
 def unlink(self, receiver=None):
     """Remove the receiver set by :meth:`link` or :meth:`rawlink`"""
     if receiver is None:
         receiver = getcurrent()
     # discarding greenlets when we have GreenletLink instances in _links works, because
     # a GreenletLink instance pretends to be a greenlet, hash-wise and eq-wise
     self._links.discard(receiver)
Example #31
0
 def _is_owned(self):
     return self._owner is getcurrent()
Example #32
0
def get_ident(gr=None):
    if gr is None:
        gr = getcurrent()
    return id(gr)
 def _set_tstate_lock(self):
     self._greenlet = getcurrent()
Example #34
0
 def _apply_immediately(self):
     # If apply() is called from one of our own
     # worker greenlets, don't spawn a new one---if we're full, that
     # could deadlock.
     return getcurrent() in self
Example #35
0
 def __init__(self):
     _DummyThread_.__init__(self)
     g = getcurrent()
     rawlink = getattr(g, 'rawlink', None)
     if rawlink is not None:
         rawlink(_cleanup)
Example #36
0
 def _set_tstate_lock(self):
     super(Thread, self)._set_tstate_lock()
     greenlet = getcurrent()
     greenlet.rawlink(self.__greenlet_finished)
 def get_dict(self):
     """Return the dict for the current thread. Raises KeyError if none
     defined."""
     thread = getcurrent()
     return self.dicts[id(thread)][1]
Example #38
0
def get_ident(gr=None):
    if gr is None:
        return id(getcurrent())
    else:
        return id(gr)