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()
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 [], [], []
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()
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
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
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
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()
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
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()
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
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:
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
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:
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()
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(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()
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 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
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
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
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
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
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
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()
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
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()
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()
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
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()
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()
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()
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)
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
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)
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()
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 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()
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
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()
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, []
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
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
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()