def wait_idle(self, timeout=1.0):
        """Wait until the rpc queue is empty.

        This method may be called either from within the event loop or from
        outside of it.  If it is called outside of the event loop it will
        block the calling thread until the rpc queue is temporarily empty.

        If it is called from within the event loop it will return an awaitable
        object that can be used to wait for the same condition.

        The awaitable object will already have a timeout if the timeout
        parameter is passed.

        Args:
            timeout (float): The maximum number of seconds to wait.
        """

        async def _awaiter():
            background_work = {x.join() for x in self._work_queues}
            for event in self._events:
                if not event.is_set():
                    background_work.add(event.wait())

            _done, pending = await asyncio.wait(background_work, timeout=timeout)
            if len(pending) > 0:
                raise TimeoutExpiredError("Timeout waiting for event loop to become idle", pending=pending)

        if self._on_emulation_thread():
            return asyncio.wait_for(_awaiter(), timeout=timeout)

        self.run_task_external(_awaiter())
        return None
Wait until the rpc queue is empty.

        This method may be called either from within the event loop or from
        outside of it.  If it is called outside of the event loop it will
        block the calling thread until the rpc queue is temporarily empty.

        If it is called from within the event loop it will return an awaitable
        object that can be used to wait for the same condition.

        The awaitable object will already have a timeout if the timeout
        parameter is passed.

        Args:
            timeout (float): The maximum number of seconds to wait.