Beispiel #1
0
 def connect(self, address):
     if self.timeout == 0.0:
         return self._sock.connect(address)
     sock = self._sock
     if isinstance(address, tuple):
         r = getaddrinfo(address[0], address[1], sock.family, sock.type, sock.proto)
         address = r[0][-1]
     if self.timeout is not None:
         timer = Timeout.start_new(self.timeout, timeout('timed out'))
     else:
         timer = None
     try:
         while True:
             err = sock.getsockopt(SOL_SOCKET, SO_ERROR)
             if err:
                 raise error(err, strerror(err))
             result = sock.connect_ex(address)
             if not result or result == EISCONN:
                 break
             elif (result in (EWOULDBLOCK, EINPROGRESS, EALREADY)) or (result == EINVAL and is_windows):
                 self._wait(self._write_event)
             else:
                 raise error(result, strerror(result))
     finally:
         if timer is not None:
             timer.cancel()
Beispiel #2
0
def select(rlist, wlist, xlist, timeout=None):
    """An implementation of :meth:`select.select` that blocks only the current greenlet.

    Note: *xlist* is ignored.
    """
    hub = get_hub()
    current = getcurrent()
    assert hub is not current, 'do not call blocking functions from the mainloop'
    allevents = []
    timeout = Timeout.start_new(timeout)
    try:
        try:
            for readfd in rlist:
                allevents.append(
                    core.read_event(get_fileno(readfd),
                                    _select_callback,
                                    arg=(current, readfd)))
            for writefd in wlist:
                allevents.append(
                    core.write_event(get_fileno(writefd),
                                     _select_callback,
                                     arg=(current, writefd)))
        except IOError, ex:
            raise error(*ex.args)
        try:
            result = hub.switch()
        except Timeout, ex:
            if ex is not timeout:
                raise
            return [], [], []
Beispiel #3
0
def joinall(greenlets, timeout=None, raise_error=False, count=None):
    from gevent.queue import Queue
    queue = Queue()
    put = queue.put
    if count is None:
        count = len(greenlets)
    timeout = Timeout.start_new(timeout)
    try:
        try:
            for greenlet in greenlets:
                greenlet.rawlink(put)
            if raise_error:
                for _ in xrange(count):
                    greenlet = queue.get()
                    if not greenlet.successful():
                        raise greenlet.exception
            else:
                for _ in xrange(count):
                    queue.get()
        except:
            if sys.exc_info()[1] is not timeout:
                raise
        finally:
            for greenlet in greenlets:
                greenlet.unlink(put)
    finally:
        timeout.cancel()
Beispiel #4
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
Beispiel #5
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
Beispiel #6
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
Beispiel #7
0
 def stop(self, timeout=0):
     """Shutdown the server."""
     for sock in self.listeners:
         sock.close()
     self.socket = []
     #2. Set "keep-alive" connections to "close"
     # TODO
     #3a. set low timeout (min(1s, timeout or 1)) on events belonging to connection (to kill long-polling connections
     # TODO
     #3. Wait until every connection is closed or timeout expires
     if self._requests:
         timer = Timeout.start_new(timeout)
         try:
             try:
                 self._no_connections_event.wait(timeout=timeout)
             except Timeout, ex:
                 if timer is not ex:
                     raise
         finally:
             timer.cancel()
     #4. forcefull close all the connections
     # TODO
     #5. free http instance
     self.http = None
     #6. notify event created in serve_forever()
     self._stopped_event.set()
Beispiel #8
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
Beispiel #9
0
def select(rlist, wlist, xlist, timeout=None):
    """An implementation of :meth:`select.select` that blocks only the current greenlet.

    Note: *xlist* is ignored.
    """
    watchers = []
    timeout = Timeout.start_new(timeout)
    loop = get_hub().loop
    io = loop.io
    MAXPRI = loop.MAXPRI
    result = SelectResult()
    try:
        try:
            for readfd in rlist:
                watcher = io(get_fileno(readfd), 1)
                watcher.priority = MAXPRI
                watcher.start(result.add_read, readfd)
                watchers.append(watcher)
            for writefd in wlist:
                watcher = io(get_fileno(writefd), 2)
                watcher.priority = MAXPRI
                watcher.start(result.add_write, writefd)
                watchers.append(watcher)
        except IOError:
            ex = sys.exc_info()[1]
            raise error(*ex.args)
        result.event.wait(timeout=timeout)
        return result.read, result.write, []
    finally:
        for watcher in watchers:
            watcher.stop()
        timeout.cancel()
Beispiel #10
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 no timeout was given, the only possible return value is ``True``.)
        """
        if self._flag:
            return self._flag

        switch = getcurrent().switch
        self.rawlink(switch)
        try:
            timer = Timeout.start_new(timeout) if timeout is not None else None
            try:
                try:
                    result = self.hub.switch()
                    if result is not self:
                        raise InvalidSwitchError('Invalid switch into Event.wait(): %r' % (result, ))
                except Timeout as ex:
                    if ex is not timer:
                        raise
            finally:
                if timer is not None:
                    timer.cancel()
        finally:
            self.unlink(switch)
        return self._flag
Beispiel #11
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:
Beispiel #12
0
 def connect(self, address):
     if self.timeout == 0.0:
         return self._sock.connect(address)
     sock = self._sock
     if isinstance(address, tuple):
         r = getaddrinfo(address[0], address[1], sock.family, sock.type,
                         sock.proto)
         address = r[0][-1]
     if self.timeout is not None:
         timer = Timeout.start_new(self.timeout, timeout('timed out'))
     else:
         timer = None
     try:
         while True:
             err = sock.getsockopt(SOL_SOCKET, SO_ERROR)
             if err:
                 raise error(err, strerror(err))
             result = sock.connect_ex(address)
             if not result or result == EISCONN:
                 break
             elif (result in (EWOULDBLOCK, EINPROGRESS,
                              EALREADY)) or (result == EINVAL
                                             and is_windows):
                 self._wait(self._write_event)
             else:
                 raise error(result, strerror(result))
     finally:
         if timer is not None:
             timer.cancel()
Beispiel #13
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
Beispiel #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).

        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
Beispiel #15
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:
Beispiel #16
0
def wait(io, timeout=None, timeout_exc=_NONE):
    """
    Block the current greenlet until *io* is ready.

    If *timeout* is non-negative, then *timeout_exc* is raised after
    *timeout* second has passed. By default *timeout_exc* is
    ``socket.timeout('timed out')``.

    If :func:`cancel_wait` is called on *io* by another greenlet,
    raise an exception in this blocking greenlet
    (``socket.error(EBADF, 'File descriptor was closed in another
    greenlet')`` by default).

    :param io: A libev watcher, most commonly an IO watcher obtained from
        :meth:`gevent.core.loop.io`
    :keyword timeout_exc: The exception to raise if the timeout expires.
        By default, a :class:`socket.timeout` exception is raised.
        If you pass a value for this keyword, it is interpreted as for
        :class:`gevent.timeout.Timeout`.
    """
    if io.callback is not None:
        raise ConcurrentObjectUseError('This socket is already used by another greenlet: %r' % (io.callback, ))
    if timeout is not None:
        timeout_exc = timeout_exc if timeout_exc is not _NONE else _timeout_error('timed out')
        timeout = Timeout.start_new(timeout, timeout_exc)

    try:
        return get_hub().wait(io)
    finally:
        if timeout is not None:
            timeout.cancel()
Beispiel #17
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
Beispiel #18
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)
Beispiel #19
0
def select(rlist, wlist, xlist, timeout=None):
    """An implementation of :meth:`select.select` that blocks only the current greenlet.

    Note: *xlist* is ignored.
    """
    watchers = []
    timeout = Timeout.start_new(timeout)
    loop = get_hub().loop
    io = loop.io
    MAXPRI = loop.MAXPRI
    result = SelectResult()
    try:
        try:
            for readfd in rlist:
                watcher = io(get_fileno(readfd), 1)
                watcher.priority = MAXPRI
                watcher.start(result.add_read, readfd)
                watchers.append(watcher)
            for writefd in wlist:
                watcher = io(get_fileno(writefd), 2)
                watcher.priority = MAXPRI
                watcher.start(result.add_write, writefd)
                watchers.append(watcher)
        except IOError:
            ex = sys.exc_info()[1]
            raise error(*ex.args)
        result.event.wait(timeout=timeout)
        return result.read, result.write, []
    finally:
        for watcher in watchers:
            watcher.stop()
        timeout.cancel()
Beispiel #20
0
def wait(io, timeout=None, timeout_exc=_NONE):
    """
    Block the current greenlet until *io* is ready.

    If *timeout* is non-negative, then *timeout_exc* is raised after
    *timeout* second has passed. By default *timeout_exc* is
    ``socket.timeout('timed out')``.

    If :func:`cancel_wait` is called on *io* by another greenlet,
    raise an exception in this blocking greenlet
    (``socket.error(EBADF, 'File descriptor was closed in another
    greenlet')`` by default).

    :param io: A libev watcher, most commonly an IO watcher obtained from
        :meth:`gevent.core.loop.io`
    :keyword timeout_exc: The exception to raise if the timeout expires.
        By default, a :class:`socket.timeout` exception is raised.
        If you pass a value for this keyword, it is interpreted as for
        :class:`gevent.timeout.Timeout`.
    """
    if io.callback is not None:
        raise ConcurrentObjectUseError(
            'This socket is already used by another greenlet: %r' %
            (io.callback, ))
    if timeout is not None:
        timeout_exc = timeout_exc if timeout_exc is not _NONE else _timeout_error(
            'timed out')
        timeout = Timeout.start_new(timeout, timeout_exc)

    try:
        return get_hub().wait(io)
    finally:
        if timeout is not None:
            timeout.cancel()
Beispiel #21
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)
Beispiel #22
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
Beispiel #23
0
 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 = get_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
Beispiel #24
0
def joinall(greenlets, timeout=None, raise_error=False, count=None):
    from gevent.queue import Queue
    queue = Queue()
    put = queue.put
    if count is None:
        count = len(greenlets)
    timeout = Timeout.start_new(timeout)
    try:
        try:
            for greenlet in greenlets:
                greenlet.rawlink(put)
            if raise_error:
                for _ in xrange(count):
                    greenlet = queue.get()
                    if not greenlet.successful():
                        raise greenlet.exception
            else:
                for _ in xrange(count):
                    queue.get()
        except:
            if sys.exc_info()[1] is not timeout:
                raise
        finally:
            for greenlet in greenlets:
                greenlet.unlink(put)
    finally:
        timeout.cancel()
Beispiel #25
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
Beispiel #26
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
Beispiel #27
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
Beispiel #28
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:
                        ex = sys.exc_info()[1]
                        if ex is not timer:
                            raise
                finally:
                    timer.cancel()
            finally:
                self.unlink(switch)
        return self._flag
Beispiel #29
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) if timeout is not None else None
        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:
            if timeout is not None:
                timeout.cancel()
Beispiel #30
0
 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
Beispiel #31
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()
Beispiel #32
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()
Beispiel #33
0
    def join(self, timeout=None):
        """Wait until the greenlet finishes or *timeout* expires.
        Return ``None`` regardless.
        """
        if self.ready():
            return

        switch = getcurrent().switch
        self.rawlink(switch)
        try:
            t = Timeout.start_new(timeout)
            try:
                result = self.parent.switch()
                if result is not self:
                    raise InvalidSwitchError(
                        'Invalid switch into Greenlet.join(): %r' % (result, ))
            finally:
                t.cancel()
        except Timeout as ex:
            self.unlink(switch)
            if ex is not t:
                raise
        except:
            self.unlink(switch)
            raise
Beispiel #34
0
 def join(self, timeout=None, raise_error=False):
     timeout = Timeout.start_new(timeout)
     try:
         try:
             while self.greenlets:
                 joinall(self.greenlets, raise_error=raise_error)
         except Timeout, ex:
             if ex is not timeout:
                 raise
     finally:
         timeout.cancel()
Beispiel #35
0
 def join(self, timeout=None, raise_error=False):
     timeout = Timeout.start_new(timeout)
     try:
         try:
             while self.greenlets:
                 joinall(self.greenlets, raise_error=raise_error)
         except Timeout, ex:
             if ex is not timeout:
                 raise
     finally:
         timeout.cancel()
Beispiel #36
0
 def kill(self, exception=GreenletExit, block=False, timeout=None):
     timer = Timeout.start_new(timeout)
     try:
         while self.greenlets:
             for greenlet in self.greenlets:
                 if greenlet not in self.dying:
                     greenlet.kill(exception)
                     self.dying.add(greenlet)
             if not block:
                 break
             joinall(self.greenlets)
     finally:
         timer.cancel()
Beispiel #37
0
 def kill(self, exception=GreenletExit, block=False, timeout=None):
     timer = Timeout.start_new(timeout)
     try:
         while self.greenlets:
             for greenlet in self.greenlets:
                 if greenlet not in self.dying:
                     greenlet.kill(exception)
                     self.dying.add(greenlet)
             if not block:
                 break
             joinall(self.greenlets)
     finally:
         timer.cancel()
Beispiel #38
0
def test_timeout(seconds, default):
    timeout = Timeout.start_new(seconds)
    try:
        try:
            return gsleep(5)
        except Timeout as t:
            # if sys.exc_info()[1] is timeout:
            if t is timeout:
                print 'timeout instance sys.exc_info()[1] is timout: %s' % (sys.exc_info()[1] is timeout)
                return default
            raise  # not my timeout
    finally:
        print 'test_timeout: cancel timeout'
        timeout.cancel()
Beispiel #39
0
def killall(greenlets, exception=GreenletExit, block=False, timeout=None):
    if block:
        waiter = Waiter()
        core.active_event(_killall3, greenlets, exception, waiter)
        if block:
            t = Timeout.start_new(timeout)
            try:
                alive = waiter.wait()
                if alive:
                    joinall(alive, raise_error=False)
            finally:
                t.cancel()
    else:
        core.active_event(_killall, greenlets, exception)
Beispiel #40
0
    def put(self, item, block=True, timeout=None):
        """Put an item into the queue.

        If optional arg *block* is true and *timeout* is ``None`` (the default),
        block if necessary until a free slot is available. If *timeout* is
        a positive number, it blocks at most *timeout* seconds and raises
        the :class:`Full` exception if no free slot was available within that time.
        Otherwise (*block* is false), put an item on the queue if a free slot
        is immediately available, else raise the :class:`Full` exception (*timeout*
        is ignored in that case).
        """
        if self.maxsize is None or self.qsize() < self.maxsize:
            # there's a free slot, put an item right away
            self._put(item)
            if self.getters:
                self._schedule_unlock()
        elif self.hub is getcurrent():
            # We're in the mainloop, so we cannot wait; we can switch to other greenlets though.
            # Check if possible to get a free slot in the queue.
            while self.getters and self.qsize(
            ) and self.qsize() >= self.maxsize:
                getter = self.getters.popleft()
                getter.switch(getter)
            if self.qsize() < self.maxsize:
                self._put(item)
                return
            raise Full
        elif block:
            waiter = ItemWaiter(item, self)
            self.putters.append(waiter)
            timeout = Timeout.start_new(timeout,
                                        Full) if timeout is not None else None
            try:
                if self.getters:
                    self._schedule_unlock()
                result = waiter.get()
                if result is not waiter:
                    raise InvalidSwitchError(
                        "Invalid switch into Queue.put: %r" % (result, ))
            finally:
                if timeout is not None:
                    timeout.cancel()
                try:
                    self.putters.remove(waiter)
                except ValueError:
                    pass  # removed by unlock
        else:
            raise Full
Beispiel #41
0
def killall(greenlets, exception=GreenletExit, block=True, timeout=None):
    if not greenlets:
        return
    loop = greenlets[0].loop
    if block:
        waiter = Waiter()
        loop.run_callback(_killall3, greenlets, exception, waiter)
        t = Timeout.start_new(timeout)
        try:
            alive = waiter.get()
            if alive:
                joinall(alive, raise_error=False)
        finally:
            t.cancel()
    else:
        loop.run_callback(_killall, greenlets, exception)
Beispiel #42
0
def killall(greenlets, exception=GreenletExit, block=True, timeout=None):
    if not greenlets:
        return
    loop = greenlets[0].loop
    if block:
        waiter = Waiter()
        loop.run_callback(_killall3, greenlets, exception, waiter)
        t = Timeout.start_new(timeout)
        try:
            alive = waiter.get()
            if alive:
                joinall(alive, raise_error=False)
        finally:
            t.cancel()
    else:
        loop.run_callback(_killall, greenlets, exception)
Beispiel #43
0
def wait(io, timeout=None, timeout_exc=timeout('timed out')):
    """Block the current greenlet until *io* is ready.

    If *timeout* is non-negative, then *timeout_exc* is raised after *timeout* second has passed.
    By default *timeout_exc* is ``socket.timeout('timed out')``.

    If :func:`cancel_wait` is called, raise ``socket.error(EBADF, 'File descriptor was closed in another greenlet')``.
    """
    assert io.callback is None, 'This socket is already used by another greenlet: %r' % (io.callback, )
    if timeout is not None:
        timeout = Timeout.start_new(timeout, timeout_exc)
    try:
        return get_hub().wait(io)
    finally:
        if timeout is not None:
            timeout.cancel()
Beispiel #44
0
def wait(io, timeout=None, timeout_exc=timeout('timed out')):
    """Block the current greenlet until *io* is ready.

    If *timeout* is non-negative, then *timeout_exc* is raised after *timeout* second has passed.
    By default *timeout_exc* is ``socket.timeout('timed out')``.

    If :func:`cancel_wait` is called, raise ``socket.error(EBADF, 'File descriptor was closed in another greenlet')``.
    """
    assert io.callback is None, 'This socket is already used by another greenlet: %r' % (io.callback, )
    if timeout is not None:
        timeout = Timeout.start_new(timeout, timeout_exc)
    try:
        return get_hub().wait(io)
    finally:
        if timeout is not None:
            timeout.cancel()
Beispiel #45
0
    def put(self, item, block=True, timeout=None):
        """Put an item into the queue.

        If optional arg *block* is true and *timeout* is ``None`` (the
        default), block if necessary until a free slot is available. If
        *timeout* is a positive number, it blocks at most *timeout*
        seconds and raises the :class:`Full` exception if no free slot
        was available within that time. Otherwise (*block* is false),
        put an item on the queue if a free slot is immediately
        available, else raise the :class:`Full` exception (*timeout* is
        ignored in that case).

        """
        if self.maxsize is None or self.qsize() < self.maxsize:
            # there's a free slot, put an item right away
            self._put(item)
            if self.getters:
                self._schedule_unlock()
        elif not block and get_hub() is getcurrent():
            # we're in the mainloop, so we cannot wait; we can switch() to other greenlets though
            # find a getter and deliver an item to it

            while self.getters and self.qsize(
            ) and self.qsize() >= self.maxsize:
                getter = self.getters.pop()
                getter.switch(getter)
            if self.qsize() < self.maxsize:
                self._put(item)
                return
            raise Full
        elif block:
            waiter = ItemWaiter(item)
            self.putters.add(waiter)
            timeout = Timeout.start_new(timeout, Full)
            try:
                if self.getters:
                    self._schedule_unlock()
                result = waiter.get()
                assert result is waiter, "Invalid switch into Queue.put: %r" % (
                    result, )
                if waiter.item is not _NONE:
                    self._put(item)
            finally:
                timeout.cancel()
                self.putters.discard(waiter)
        else:
            raise Full
Beispiel #46
0
 def kill(self, exception=GreenletExit, block=True, timeout=None):
     timer = Timeout.start_new(timeout)
     try:
         try:
             while self.greenlets:
                 for greenlet in list(self.greenlets):
                     if greenlet not in self.dying:
                         greenlet.kill(exception, block=False)
                         self.dying.add(greenlet)
                 if not block:
                     break
                 joinall(self.greenlets)
         except Timeout, ex:
             if ex is not timer:
                 raise
     finally:
         timer.cancel()
Beispiel #47
0
 def kill(self, exception=GreenletExit, block=True, timeout=None):
     timer = Timeout.start_new(timeout)
     try:
         try:
             while self.greenlets:
                 for greenlet in list(self.greenlets):
                     if greenlet not in self.dying:
                         greenlet.kill(exception, block=False)
                         self.dying.add(greenlet)
                 if not block:
                     break
                 joinall(self.greenlets)
         except Timeout, ex:
             if ex is not timer:
                 raise
     finally:
         timer.cancel()
Beispiel #48
0
    def put(self, item, block=True, timeout=None):
        """Put an item into the queue.

        If optional arg *block* is true and *timeout* is ``None`` (the
        default), block if necessary until a free slot is available. If
        *timeout* is a positive number, it blocks at most *timeout*
        seconds and raises the :class:`Full` exception if no free slot
        was available within that time. Otherwise (*block* is false),
        put an item on the queue if a free slot is immediately
        available, else raise the :class:`Full` exception (*timeout* is
        ignored in that case).

        """
        if self.maxsize is None or self.qsize() < self.maxsize:
            # there's a free slot, put an item right away
            self._put(item)
            if self.getters:
                self._schedule_unlock()
        elif not block and get_hub() is getcurrent():
            # we're in the mainloop, so we cannot wait; we can switch() to other greenlets though
            # find a getter and deliver an item to it

            while self.getters and self.qsize() and self.qsize() >= self.maxsize:
                getter = self.getters.pop()
                getter.switch(getter)
            if self.qsize() < self.maxsize:
                self._put(item)
                return
            raise Full
        elif block:
            waiter = ItemWaiter(item)
            self.putters.add(waiter)
            timeout = Timeout.start_new(timeout, Full)
            try:
                if self.getters:
                    self._schedule_unlock()
                result = waiter.get()
                assert result is waiter, "Invalid switch into Queue.put: %r" % (result,)
                if waiter.item is not _NONE:
                    self._put(item)
            finally:
                timeout.cancel()
                self.putters.discard(waiter)
        else:
            raise Full
    def put(self, item, block=True, timeout=None):
        """Put an item into the queue.

        If optional arg *block* is true and *timeout* is ``None`` (the default),
        block if necessary until a free slot is available. If *timeout* is
        a positive number, it blocks at most *timeout* seconds and raises
        the :class:`Full` exception if no free slot was available within that time.
        Otherwise (*block* is false), put an item on the queue if a free slot
        is immediately available, else raise the :class:`Full` exception (*timeout*
        is ignored in that case).
        """
        if self.maxsize is None or self.qsize() < self.maxsize:
            # there's a free slot, put an item right away
            self._put(item)
            if self.getters:
                self._schedule_unlock()
        elif self.hub is getcurrent():
            # We're in the mainloop, so we cannot wait; we can switch to other greenlets though.
            # Check if possible to get a free slot in the queue.
            while self.getters and self.qsize() and self.qsize() >= self.maxsize:
                getter = self.getters.popleft()
                getter.switch(getter)
            if self.qsize() < self.maxsize:
                self._put(item)
                return
            raise Full
        elif block:
            waiter = ItemWaiter(item, self)
            self.putters.append(waiter)
            timeout = Timeout.start_new(timeout, Full) if timeout is not None else None
            try:
                if self.getters:
                    self._schedule_unlock()
                result = waiter.get()
                if result is not waiter:
                    raise InvalidSwitchError("Invalid switch into Queue.put: %r" % (result, ))
            finally:
                if timeout is not None:
                    timeout.cancel()
                try:
                    self.putters.remove(waiter)
                except ValueError:
                    pass # removed by unlock
        else:
            raise Full
Beispiel #50
0
    def _wait(self, watcher, timeout_exc=timeout('timed out')):
        """Block the current greenlet until *watcher* has pending events.

        If *timeout* is non-negative, then *timeout_exc* is raised after *timeout* second has passed.
        By default *timeout_exc* is ``socket.timeout('timed out')``.

        If :func:`cancel_wait` is called, raise ``socket.error(EBADF, 'File descriptor was closed in another greenlet')``.
        """
        assert watcher.callback is None, 'This socket is already used by another greenlet: %r' % (watcher.callback, )
        if self.timeout is not None:
            timeout = Timeout.start_new(self.timeout, timeout_exc, ref=False)
        else:
            timeout = None
        try:
            self.hub.wait(watcher)
        finally:
            if timeout is not None:
                timeout.cancel()
Beispiel #51
0
def select(rlist, wlist, xlist, timeout=None):
    """An implementation of :meth:`select.select` that blocks only the current greenlet.

    Note: *xlist* is ignored.
    """
    allevents = []
    timeout = Timeout.start_new(timeout)
    result = SelectResult()
    try:
        try:
            for readfd in rlist:
                allevents.append(core.read_event(get_fileno(readfd), result.update, arg=readfd))
            for writefd in wlist:
                allevents.append(core.write_event(get_fileno(writefd), result.update, arg=writefd))
        except IOError, ex:
            raise error(*ex.args)
        result.event.wait(timeout=timeout)
        return result.read, result.write, []
Beispiel #52
0
    def _wait(self, watcher, timeout_exc=timeout('timed out')):
        """Block the current greenlet until *watcher* has pending events.

        If *timeout* is non-negative, then *timeout_exc* is raised after *timeout* second has passed.
        By default *timeout_exc* is ``socket.timeout('timed out')``.

        If :func:`cancel_wait` is called, raise ``socket.error(EBADF, 'File descriptor was closed in another greenlet')``.
        """
        assert watcher.callback is None, 'This socket is already used by another greenlet: %r' % (watcher.callback, )
        if self.timeout is not None:
            timeout = Timeout.start_new(self.timeout, timeout_exc, ref=False)
        else:
            timeout = None
        try:
            self.hub.wait(watcher)
        finally:
            if timeout is not None:
                timeout.cancel()
Beispiel #53
0
    def get(self, block=True, timeout=None):
        """Remove and return an item from the queue.

        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():
            if self.putters:
                self._schedule_unlock()
            return self._get()
        elif self.hub is getcurrent():
            # special case to make get_nowait() 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.popleft().put_and_switch()
                if self.qsize():
                    return self._get()
            raise Empty
        elif block:
            waiter = Waiter()
            timeout = Timeout.start_new(timeout,
                                        Empty) if timeout is not None else None
            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 self._get()
            finally:
                if timeout is not None:
                    timeout.cancel()
                try:
                    self.getters.remove(waiter)
                except ValueError:
                    pass  # Removed by _unlock
        else:
            raise Empty
    def get(self, block=True, timeout=None):
        """Remove and return an item from the queue.

        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():
            if self.putters:
                self._schedule_unlock()
            return self._get()
        elif self.hub is getcurrent():
            # special case to make get_nowait() 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.popleft().put_and_switch()
                if self.qsize():
                    return self._get()
            raise Empty
        elif block:
            waiter = Waiter()
            timeout = Timeout.start_new(timeout, Empty) if timeout is not None else None
            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 self._get()
            finally:
                if timeout is not None:
                    timeout.cancel()
                try:
                    self.getters.remove(waiter)
                except ValueError:
                    pass # Removed by _unlock
        else:
            raise Empty
Beispiel #55
0
    def wait(self, timeout=None):
        """Block until the instance is ready.

        If this instance already holds a value, it is returned immediately. If this
        instance already holds an exception, ``None`` is returned immediately.

        Otherwise, block until another greenlet calls :meth:`set` or :meth:`set_exception`
        (at which point either the value or ``None`` will be returned, respectively),
        or until the optional timeout expires (at which point ``None`` will also be
        returned).

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

        .. note:: If a timeout is given and expires, ``None`` will be returned
            (no timeout exception will be raised).

        """
        if self.ready():
            return self.value

        switch = getcurrent().switch
        self.rawlink(switch)
        try:
            timer = Timeout.start_new(timeout)
            try:
                result = self.hub.switch()
                if result is not self:
                    raise InvalidSwitchError('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
Beispiel #56
0
def joinall(greenlets, timeout=None, raise_error=False):
    from gevent.queue import Queue
    queue = Queue()
    put = queue.put
    timeout = Timeout.start_new(timeout)
    try:
        try:
            for greenlet in greenlets:
                greenlet.rawlink(put)
            for _ in xrange(len(greenlets)):
                greenlet = queue.get()
                if raise_error and not greenlet.successful():
                    getcurrent().throw(greenlet.exception)
        except:
            for greenlet in greenlets:
                greenlet.unlink(put)
            if sys.exc_info()[1] is not timeout:
                raise
    finally:
        timeout.cancel()