def join(self, timeout=None):
        """Rejoin the server thread.

        Parameters
        ----------
        timeout : float or None, optional
            Time in seconds to wait for the thread to finish.

        Notes
        -----
        If the ioloop is not managed, this function will block until the server
        port is closed, meaning a new server can be started on the same port.

        """
        t0 = time.time()
        self._ioloop_manager.join(timeout=timeout)
        if timeout:
            self._stopped.wait(timeout - (time.time() - t0))