def stop(self, timeout=None, callback=None):
        """Stop ioloop (if managed) and call callback in ioloop before close.

        Parameters
        ----------
        timeout : float or None
            Seconds to wait for ioloop to have *started*.

        Returns
        -------
        stopped : thread-safe Future
            Resolves when the callback() is done

        """
        if timeout:
            self._running.wait(timeout)

        stopped_future = Future()

        @gen.coroutine
        def _stop():
            if callback:
                try:
                    yield gen.maybe_future(callback())
                except Exception:
                    self._logger.exception('Unhandled exception calling stop callback')
            if self._ioloop_managed:
                self._logger.info('Stopping ioloop {0!r}'.format(self._ioloop))
                # Allow ioloop to run once before stopping so that callbacks
                # scheduled by callback() above get a chance to run.
                yield gen.moment
                self._ioloop.stop()
            self._running.clear()

        try:
            self._ioloop.add_callback(
                lambda: gen.chain_future(_stop(), stopped_future))
        except AttributeError:
            # Probably we have been shut-down already
            pass

        return stopped_future