def kill(self, exception=GreenletExit, block=True, timeout=None): """ Kill all greenlets being tracked by this group. """ timer = Timeout._start_new_or_dummy(timeout) try: try: while self.greenlets: for greenlet in list(self.greenlets): if greenlet not in self.dying: try: kill = greenlet.kill except AttributeError: _kill(greenlet, exception) else: kill(exception, block=False) self.dying.add(greenlet) if not block: break joinall(self.greenlets) except Timeout as ex: if ex is not timer: raise finally: timer.cancel()
def kill(self, exception=GreenletExit, block=True, timeout=None): """ Kill all greenlets being tracked by this group. """ timer = Timeout._start_new_or_dummy(timeout) try: while self.greenlets: for greenlet in list(self.greenlets): if greenlet in self.dying: continue try: kill = greenlet.kill except AttributeError: _kill(greenlet, exception) else: kill(exception, block=False) self.dying.add(greenlet) if not block: break joinall(self.greenlets) except Timeout as ex: if ex is not timer: raise finally: timer.cancel()
def communicate(self, input=None): """Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate. The optional input argument should be a string to be sent to the child process, or None, if no data should be sent to the child. communicate() returns a tuple (stdout, stderr).""" greenlets = [] if self.stdin: greenlets.append(spawn(write_and_close, self.stdin, input)) if self.stdout: stdout = spawn(self.stdout.read) greenlets.append(stdout) else: stdout = None if self.stderr: stderr = spawn(self.stderr.read) greenlets.append(stderr) else: stderr = None joinall(greenlets) if self.stdout: self.stdout.close() if self.stderr: self.stderr.close() self.wait() return (None if stdout is None else stdout.value or '', None if stderr is None else stderr.value or '')
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 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 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: try: kill = greenlet.kill except AttributeError: _kill(greenlet, exception) else: kill(exception, block=False) self.dying.add(greenlet) if not block: break joinall(self.greenlets) except Timeout: ex = sys.exc_info()[1] if ex is not timer: raise finally: timer.cancel()
def get_values(greenlets): joinall(greenlets) return [x.value for x in greenlets]
def communicate(self, input=None, timeout=None): """Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate. The optional input argument should be a string to be sent to the child process, or None, if no data should be sent to the child. communicate() returns a tuple (stdout, stderr). :keyword timeout: Under Python 2, this is a gevent extension; if given and it expires, we will raise :class:`gevent.timeout.Timeout`. Under Python 3, this raises the standard :exc:`TimeoutExpired` exception. """ greenlets = [] if self.stdin: greenlets.append(spawn(write_and_close, self.stdin, input)) # If the timeout parameter is used, and the caller calls back after # getting a TimeoutExpired exception, we can wind up with multiple # greenlets trying to run and read from and close stdout/stderr. # That's bad because it can lead to 'RuntimeError: reentrant call in io.BufferedReader'. # We can't just kill the previous greenlets when a timeout happens, # though, because we risk losing the output collected by that greenlet # (and Python 3, where timeout is an official parameter, explicitly says # that no output should be lost in the event of a timeout.) Instead, we're # watching for the exception and ignoring it. It's not elegant, # but it works if self.stdout: def _read_out(): try: data = self.stdout.read() except RuntimeError: return if self._stdout_buffer is not None: self._stdout_buffer += data else: self._stdout_buffer = data stdout = spawn(_read_out) greenlets.append(stdout) else: stdout = None if self.stderr: def _read_err(): try: data = self.stderr.read() except RuntimeError: return if self._stderr_buffer is not None: self._stderr_buffer += data else: self._stderr_buffer = data stderr = spawn(_read_err) greenlets.append(stderr) else: stderr = None # If we were given stdin=stdout=stderr=None, we have no way to # communicate with the child, and thus no greenlets to wait # on. This is a nonsense case, but it comes up in the test # case for Python 3.5 (test_subprocess.py # RunFuncTestCase.test_timeout). Instead, we go directly to # self.wait if not greenlets and timeout is not None: result = self.wait(timeout=timeout) # Python 3 would have already raised, but Python 2 would not # so we need to do that manually if result is None: from gevent.timeout import Timeout raise Timeout(timeout) done = joinall(greenlets, timeout=timeout) if timeout is not None and len(done) != len(greenlets): if PY3: raise TimeoutExpired(self.args, timeout) from gevent.timeout import Timeout raise Timeout(timeout) if self.stdout: try: self.stdout.close() except RuntimeError: pass if self.stderr: try: self.stderr.close() except RuntimeError: pass self.wait() stdout_value = self._stdout_buffer self._stdout_buffer = None stderr_value = self._stderr_buffer self._stderr_buffer = None # XXX: Under python 3 in universal newlines mode we should be # returning str, not bytes return (None if stdout is None else stdout_value or b'', None if stderr is None else stderr_value or b'')