A wait callback to allow greenlet to work with Psycopg.
    The caller must be from a greenlet other than the main one.

    :param conn: psycopg2 connection or file number

    This function must be invoked from a coroutine with parent, therefore
    invoking it from the main greenlet will raise an exception.

def psycopg2_wait_callback(conn):
    """A wait callback to allow greenlet to work with Psycopg.
    The caller must be from a greenlet other than the main one.

    :param conn: psycopg2 connection or file number

    This function must be invoked from a coroutine with parent, therefore
    invoking it from the main greenlet will raise an exception.
    """
    while True:
        state = conn.poll()
        if state == extensions.POLL_OK:
            # Done with waiting
            break
        elif state == extensions.POLL_READ:
            _wait_fd(conn)
        elif state == extensions.POLL_WRITE:
            _wait_fd(conn, read=False)
        else:  # pragma    nocover
            raise OperationalError("Bad result from poll: %r" % state)