Adds a ready event to BackgroundConsumer to wait on start. (#7499)

* Adds a ready event to BackgroundConsumer to allow waiting for the background thread to start

diff --git a/google/api_core/bidi.py b/google/api_core/bidi.py
index 795a8d2..68d1300 100644
--- a/google/api_core/bidi.py
+++ b/google/api_core/bidi.py
@@ -505,8 +505,9 @@
         # when the RPC has terminated.
         self.resume()
 
-    def _thread_main(self):
+    def _thread_main(self, ready):
         try:
+            ready.set()
             self._bidi_rpc.add_done_callback(self._on_call_done)
             self._bidi_rpc.open()
 
@@ -555,11 +556,19 @@
     def start(self):
         """Start the background thread and begin consuming the thread."""
         with self._operational_lock:
+            ready = threading.Event()
             thread = threading.Thread(
-                name=_BIDIRECTIONAL_CONSUMER_NAME, target=self._thread_main
+                name=_BIDIRECTIONAL_CONSUMER_NAME,
+                target=self._thread_main,
+                args=(ready,)
             )
             thread.daemon = True
             thread.start()
+            # Other parts of the code rely on `thread.is_alive` which
+            # isn't sufficient to know if a thread is active, just that it may
+            # soon be active. This can cause races. Further protect
+            # against races by using a ready event and wait on it to be set.
+            ready.wait()
             self._thread = thread
             _LOGGER.debug("Started helper thread %s", thread.name)