def run_and_respawn(shutdown, loop=None, **kwds):
    """Starts a child process and re-spawns it every time it completes.

    .. note:: This function is a coroutine.

    :param shutdown: Future that the caller will fulfill to indicate that the
       process should not be re-spawned.  It is also passed to ``run_once()``
       to indicate that the currently running process should be killed early.
    :param loop: Event loop to use.  Defaults to the
       ``asyncio.get_event_loop()``.
    :param kwds: Arguments to forward to :py:func:`run_once`.
    :return: A future that will be completed when the process has stopped
       re-spawning and has completed.  The future has no result.

    """

    # Get the default event loop if necessary.
    loop = loop or asyncio.get_event_loop()

    while not shutdown.done():
        t = loop.create_task(run_once(shutdown=shutdown, loop=loop, **kwds))
        yield from t
Starts a child process and re-spawns it every time it completes.

    .. note:: This function is a coroutine.

    :param shutdown: Future that the caller will fulfill to indicate that the
       process should not be re-spawned.  It is also passed to ``run_once()``
       to indicate that the currently running process should be killed early.
    :param loop: Event loop to use.  Defaults to the
       ``asyncio.get_event_loop()``.
    :param kwds: Arguments to forward to :py:func:`run_once`.
    :return: A future that will be completed when the process has stopped
       re-spawning and has completed.  The future has no result.