start a server that runs python interpreters on connections made to it

    .. note::

        this function blocks effectively indefinitely -- it runs the listening
        socket loop in the current greenlet. to keep the current greenlet free,
        :func:`schedule<greenhouse.scheduler.schedule>` this function.

    :param address:
        the address on which to listen for backdoor connections, in the form of
        a two-tuple ``(host, port)``
    :type address: tuple
    :param namespace:
        the local namespace dict for the interpreter, or None to have each
        connection create its own empty namespace
    :type namespace: dict or None

def run_backdoor(address, namespace=None):
    """start a server that runs python interpreters on connections made to it

    .. note::

        this function blocks effectively indefinitely -- it runs the listening
        socket loop in the current greenlet. to keep the current greenlet free,
        :func:`schedule<greenhouse.scheduler.schedule>` this function.

    :param address:
        the address on which to listen for backdoor connections, in the form of
        a two-tuple ``(host, port)``
    :type address: tuple
    :param namespace:
        the local namespace dict for the interpreter, or None to have each
        connection create its own empty namespace
    :type namespace: dict or None
    """
    log.info("starting on %r" % (address,))
    serversock = io.Socket()
    serversock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    serversock.bind(address)
    serversock.listen(socket.SOMAXCONN)

    while 1:
        clientsock, address = serversock.accept()
        log.info("connection received from %r" % (address,))
        scheduler.schedule(backdoor_handler, args=(clientsock, namespace))