return result

        gotit = self._wait_core(timeout)
        return self._wait_return_value(True, gotit)

    def _at_fork_reinit(self):
        """
        This method was added in Python 3.9 and is called by logging.py
        ``_after_at_fork_child_reinit_locks`` on Lock objects.

        It is also called from threading.py, ``_after_fork`` in
        ``_reset_internal_locks``, and that can hit ``Event`` objects.

        Subclasses should reset themselves to an initial state. This
        includes unlocking/releasing, if possible. This method detaches from the
        previous hub and drops any existing notifier.
        """
        self.hub = None
        self._notifier = None


def _init():
    greenlet_init()  # pylint:disable=undefined-variable


_init()

from gevent._util import import_c_accel
import_c_accel(globals(), 'gevent.__abstract_linkable')
Esempio n. 2
0
            timeout.close()

    def get_nowait(self):
        return self.get(False)

    def _unlock(self):
        while self.putters and self.getters:
            getter = self.getters.popleft()
            item, putter = self.putters.popleft()
            getter.switch(item)
            putter.switch(putter)

    def _schedule_unlock(self):
        if not self._event_unlock:
            self._event_unlock = self.hub.loop.run_callback(self._unlock)

    def __iter__(self):
        return self

    def __next__(self):
        result = self.get()
        if result is StopIteration:
            raise result
        return result

    next = __next__  # Py2


from gevent._util import import_c_accel
import_c_accel(globals(), 'gevent._queue')
Esempio n. 3
0
    def __call__(self, source):
        if source.successful():
            self.set(source.value)
        else:
            self.set_exception(source.exception,
                               getattr(source, 'exc_info', None))

    # Methods to make us more like concurrent.futures.Future

    def result(self, timeout=None):
        return self.get(timeout=timeout)

    set_result = set

    def done(self):
        return self.ready()

    # we don't support cancelling

    def cancel(self):
        return False

    def cancelled(self):
        return False

    # exception is a method, we use it as a property


from gevent._util import import_c_accel
import_c_accel(globals(), 'gevent._event')
Esempio n. 4
0
    If not given, *value* defaults to 1.
    """

    #: For monkey-patching, allow changing the class of error we raise
    _OVER_RELEASE_ERROR = ValueError

    def __init__(self, *args, **kwargs):
        Semaphore.__init__(self, *args, **kwargs)
        self._initial_value = self.counter

    def release(self):
        if self.counter >= self._initial_value:
            raise self._OVER_RELEASE_ERROR("Semaphore released too many times")
        Semaphore.release(self)


# By building the semaphore with Cython under PyPy, we get
# atomic operations (specifically, exiting/releasing), at the
# cost of some speed (one trivial semaphore micro-benchmark put the pure-python version
# at around 1s and the compiled version at around 4s). Some clever subclassing
# and having only the bare minimum be in cython might help reduce that penalty.
# NOTE: You must use version 0.23.4 or later to avoid a memory leak.
# https://mail.python.org/pipermail/cython-devel/2015-October/004571.html
# However, that's all for naught on up to and including PyPy 4.0.1 which
# have some serious crashing bugs with GC interacting with cython.
# It hasn't been tested since then, and PURE_PYTHON is assumed to be true
# for PyPy in all cases anyway, so this does nothing.

from gevent._util import import_c_accel
import_c_accel(globals(), 'gevent.__semaphore')
Esempio n. 5
0
    # too when we do it this way....except on PyPy3, which does
    # not *unless* it's wrapped in a classmethod (which it is)
    self.__cinit__(*args[1:], **kw)
    return self


try:
    # PyPy2/3 and CPython handle adding a __new__ to the class
    # in different ways. In CPython and PyPy3, it must be wrapped with classmethod;
    # in PyPy2, it must not. In either cases, the args that get passed to
    # it are stil wrong.
    local.__new__ = 'None'
except TypeError:  # pragma: no cover
    # Must be compiled
    pass
else:
    from gevent._compat import PYPY
    from gevent._compat import PY2
    if PYPY and PY2:
        local.__new__ = __new__
    else:
        local.__new__ = classmethod(__new__)

    del PYPY
    del PY2

_init()

from gevent._util import import_c_accel
import_c_accel(globals(), 'gevent._local')
Esempio n. 6
0
        *greenlets* can be any iterable of greenlets, like an iterator or a set.
        Previously it had to be a list or tuple.
    """
    # support non-indexable containers like iterators or set objects
    greenlets = list(greenlets)
    if not greenlets:
        return
    loop = greenlets[0].loop
    if block:
        waiter = Waiter()  # pylint:disable=undefined-variable
        loop.run_callback(_killall3, greenlets, exception, waiter)
        t = Timeout._start_new_or_dummy(timeout)
        try:
            alive = waiter.get()
            if alive:
                joinall(alive, raise_error=False)
        finally:
            t.cancel()
    else:
        loop.run_callback(_killall, greenlets, exception)


def _init():
    greenlet_init()  # pylint:disable=undefined-variable


_init()

from gevent._util import import_c_accel
import_c_accel(globals(), 'gevent._greenlet')
Esempio n. 7
0
    __slots__ = ['_values']

    def __init__(self, hub=None):
        Waiter.__init__(self, hub)
        # we typically expect a relatively small number of these to be outstanding.
        # since we pop from the left, a deque might be slightly
        # more efficient, but since we're in the hub we avoid imports if
        # we can help it to better support monkey-patching, and delaying the import
        # here can be impractical (see https://github.com/gevent/gevent/issues/652)
        self._values = list()

    def switch(self, value):
        self._values.append(value)
        Waiter.switch(self, True)

    def get(self):
        if not self._values:
            Waiter.get(self)
            Waiter.clear(self)

        return self._values.pop(0)

def _init():
    greenlet_init() # pylint:disable=undefined-variable

_init()


from gevent._util import import_c_accel
import_c_accel(globals(), 'gevent.__waiter')
Esempio n. 8
0
    # We don't specifically test for this leak.

    # https://github.com/gevent/gevent/issues/1318
    try:
        mv = _memoryview(data) if not isinstance(data, _memoryview) else data
        if mv.shape:
            return mv
        # No shape, probably working with a ctypes object,
        # or something else exotic that supports the buffer interface
        return mv.tobytes()
    except TypeError:
        # fixes "python2.7 array.array doesn't support memoryview used in
        # gevent.socket.send" issue
        # (http://code.google.com/p/gevent/issues/detail?id=94)
        if _buffer is _memoryview:
            # Py3
            raise
        return _buffer(data)


def _init():
    greenlet_init()  # pylint:disable=undefined-variable


_init()

from gevent._util import import_c_accel

import_c_accel(globals(), 'gevent.__greenlet_primitives')
Esempio n. 9
0
        except KeyError:
            # Wait for our index to finish.
            while 1:
                index, value = self.queue.get()
                if index == self.index:
                    break
                else:
                    self._results[index] = value
        self.index += 1
        return value

    def _iqueue_value_for_success(self, greenlet):
        return (greenlet._imap_task_index,
                IMapUnordered._iqueue_value_for_success(self, greenlet))

    def _iqueue_value_for_failure(self, greenlet):
        return (greenlet._imap_task_index,
                IMapUnordered._iqueue_value_for_failure(self, greenlet))

    def _iqueue_value_for_self_finished(self):
        return (self._max_index + 1,
                IMapUnordered._iqueue_value_for_self_finished(self))

    def _iqueue_value_for_self_failure(self, exception):
        return (self._max_index + 1,
                IMapUnordered._iqueue_value_for_self_failure(self, exception))


from gevent._util import import_c_accel
import_c_accel(globals(), 'gevent.__imap')
Esempio n. 10
0
class MaxSwitchTracer(_HubTracer):
    # A greenlet tracer that records the maximum time between switches,
    # not including time spent in the hub.

    def __init__(self, hub, max_blocking_time):
        _HubTracer.__init__(self, hub, max_blocking_time)
        self.last_switch = perf_counter()
        self.max_blocking = 0

    def _trace(self, event, args):
        old_active = self.active_greenlet
        GreenletTracer._trace(self, event, args)
        if old_active is not self.hub and old_active is not None:
            # If we're switching out of the hub, the blocking
            # time doesn't count.
            switched_at = perf_counter()
            self.max_blocking = max(self.max_blocking,
                                    switched_at - self.last_switch)

    def did_block_hub(self, hub):
        if self.max_blocking == 0:
            # We never switched. Check the time now
            self.max_blocking = perf_counter() - self.last_switch

        if self.max_blocking > self.max_blocking_time:
            return True, self.active_greenlet


from gevent._util import import_c_accel
import_c_accel(globals(), 'gevent.__tracer')
    Block the current greenlet until *fileno* is ready to read or
    write.

    For the meaning of the other parameters and possible exceptions,
    see :func:`wait`.

    .. deprecated:: 1.1
       The keyword argument *event* is ignored. Applications should not pass this parameter.
       In the future, doing so will become an error.

    .. seealso:: :func:`cancel_wait`
    """
    # pylint:disable=unused-argument
    hub = get_hub()
    io = hub.loop.io(fileno, 3)
    try:
        return wait_on_watcher(io, timeout, timeout_exc, hub)
    finally:
        io.close()


def _init():
    greenlet_init()  # pylint:disable=undefined-variable


_init()

from gevent._util import import_c_accel
import_c_accel(globals(), 'gevent.__hub_primitives')