'Flush output and process input while waiting for any of the given
callbacks to return true. The wait is aborted upon connection-close.
Otherwise, processing continues until the output is flushed AND at least
one of the callbacks returns true. If there are no callbacks, then
processing ends when all output is flushed.
:param waiters: sequence of zero or more callables taking no args and
returning true when it\'s time to stop processing.
Their results are OR\'ed together.'

def _flush_output(self, *waiters):

    if self.is_closed:
        raise exceptions.ConnectionClosed()
    is_done = (lambda : (self._closed_result.ready or ((not self._impl.outbound_buffer) and ((not waiters) or any((ready() for ready in waiters))))))
    while (not is_done()):
        self._impl.ioloop.poll()
        self._impl.ioloop.process_timeouts()
    if (self._open_error_result.ready or self._closed_result.ready):
        try:
            if (not self._user_initiated_close):
                if self._open_error_result.ready:
                    maybe_exception = self._open_error_result.value.error
                    LOGGER.error('Connection    open    failed    -    %r', maybe_exception)
                    if isinstance(maybe_exception, Exception):
                        raise maybe_exception
                    else:
                        raise exceptions.ConnectionClosed(maybe_exception)
                else:
                    result = self._closed_result.value
                    LOGGER.error('Connection    close    detected;    result=%r', result)
                    raise exceptions.ConnectionClosed(result.reason_code, result.reason_text)
            else:
                LOGGER.info('Connection    closed;    result=%r', self._closed_result.value)
        finally:
            self._cleanup()
