Submit Tornado Coroutine to IOLoop in daemonized thread.

        :param fn: Tornado Coroutine to execute
        :param args: Args to pass to coroutine
        :param kwargs: Kwargs to pass to coroutine
        :returns concurrent.futures.Future: future result of coroutine

def submit(self, fn, *args, **kwargs):
        """Submit Tornado Coroutine to IOLoop in daemonized thread.

        :param fn: Tornado Coroutine to execute
        :param args: Args to pass to coroutine
        :param kwargs: Kwargs to pass to coroutine
        :returns concurrent.futures.Future: future result of coroutine
        """
        if not self.is_ready():
            raise ThreadNotStartedError(
                "The thread has not been started yet, "
                "make sure you call start() first"
            )

        future = Future()

        def execute():
            """Executes fn on the IOLoop."""
            try:
                result = gen.maybe_future(fn(*args, **kwargs))
            except Exception:
                # The function we ran didn't return a future and instead raised
                # an exception. Let's pretend that it returned this dummy
                # future with our stack trace.
                f = gen.Future()
                f.set_exc_info(sys.exc_info())
                on_done(f)
            else:
                result.add_done_callback(on_done)

        def on_done(f):
            """Sets tornado.Future results to the concurrent.Future."""

            if not f.exception():
                future.set_result(f.result())
                return

            # if f is a tornado future, then it has exc_info()
            if hasattr(f, 'exc_info'):
                exception, traceback = f.exc_info()[1:]

            # else it's a concurrent.future
            else:
                # python2's concurrent.future has exception_info()
                if hasattr(f, 'exception_info'):
                    exception, traceback = f.exception_info()

                # python3's concurrent.future just has exception()
                else:
                    exception = f.exception()
                    traceback = None

            # python2 needs exc_info set explicitly
            if _FUTURE_HAS_EXC_INFO:
                future.set_exception_info(exception, traceback)
                return

            # python3 just needs the exception, exc_info works fine
            future.set_exception(exception)

        self._io_loop.add_callback(execute)

        return future