

@util.debuglog
def reap_process(self, pid, status=None):
    'ensure that the process is killed (and not a zombie)'
    if (pid not in self.processes):
        return
    process = self.processes.pop(pid)
    timeout = 0.001
    while (status is None):
        if IS_WINDOWS:
            try:
                status = process.wait(timeout=timeout)
            except TimeoutExpired:
                continue
        else:
            try:
                (_, status) = os.waitpid(pid, os.WNOHANG)
            except OSError as e:
                if (e.errno == errno.EAGAIN):
                    time.sleep(timeout)
                    continue
                elif (e.errno == errno.ECHILD):
                    status = None
                else:
                    raise
        if (status is None):
            logger.debug('reaping already dead process %s [%s]', pid, self.name)
            self.notify_event('reap', {
                'process_pid': pid,
                'time': time.time(),
                'exit_code': process.returncode(),
            })
            process.stop()
            return
    if hasattr(os, 'WIFSIGNALED'):
        exit_code = 0
        if os.WIFSIGNALED(status):
            exit_code = (- os.WTERMSIG(status))
        elif os.WIFEXITED(status):
            exit_code = os.WEXITSTATUS(status)
        else:
            raise RuntimeError('Unknown process exit status')
    else:
        exit_code = status
    if (process.status in (DEAD_OR_ZOMBIE, UNEXISTING)):
        process.stop()
    logger.debug('reaping process %s [%s]', pid, self.name)
    self.notify_event('reap', {
        'process_pid': pid,
        'time': time.time(),
        'exit_code': exit_code,
    })

dataset/ETHPy150Open circus-tent/circus/circus/watcher.py Watcher.reap_process/original