Index: /trunk/src/VBox/Devices/Audio/DrvAudio.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DrvAudio.cpp	(revision 86562)
+++ /trunk/src/VBox/Devices/Audio/DrvAudio.cpp	(revision 86563)
@@ -764,5 +764,9 @@
     PPDMAUDIOSTREAM pStream;
     RTListForEach(&pThis->lstStreams, pStream, PDMAUDIOSTREAM, Node)
+    {
         pStream->fStatus |= PDMAUDIOSTREAMSTS_FLAGS_PENDING_REINIT;
+        pStream->cTriesReInit   = 0;
+        pStream->tsLastReInitNs = 0;
+    }
 
 # ifdef VBOX_WITH_AUDIO_ENUM
@@ -780,4 +784,6 @@
  * on the host side has changed.
  *
+ * Note: Does not touch the stream's status flags.
+ *
  * @returns IPRT status code.
  * @param   pThis               Pointer to driver instance.
@@ -794,5 +800,5 @@
      * Gather current stream status.
      */
-    bool fIsEnabled = RT_BOOL(pStream->fStatus & PDMAUDIOSTREAMSTS_FLAGS_ENABLED); /* Stream is enabled? */
+    const bool fIsEnabled = RT_BOOL(pStream->fStatus & PDMAUDIOSTREAMSTS_FLAGS_ENABLED); /* Stream is enabled? */
 
     /*
@@ -869,5 +875,4 @@
 
     pStream->fStatus = PDMAUDIOSTREAMSTS_FLAGS_INITIALIZED;
-
 #ifdef VBOX_WITH_STATISTICS
     /*
@@ -1111,31 +1116,63 @@
  * Re-initializes the given stream if it is scheduled for this operation.
  *
- * @returns VBox status code.
  * @param   pThis               Pointer to driver instance.
  * @param   pStream             Stream to check and maybe re-initialize.
  */
-static int drvAudioStreamMaybeReInit(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream)
-{
-    int rc = VINF_SUCCESS;
-
+static void drvAudioStreamMaybeReInit(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream)
+{
     if (pStream->fStatus & PDMAUDIOSTREAMSTS_FLAGS_PENDING_REINIT)
     {
+        const unsigned cMaxTries = 3; /** @todo Make this configurable? */
+        const uint64_t tsNowNs   = RTTimeNanoTS();
+
+        /* Throttle re-initializing streams on failure. */
+        if (   pStream->cTriesReInit < cMaxTries
+            && tsNowNs - pStream->tsLastReInitNs >= RT_NS_1SEC * pStream->cTriesReInit) /** @todo Ditto. */
+        {
 #ifdef VBOX_WITH_AUDIO_ENUM
-        if (pThis->fEnumerateDevices)
-        {
-            /* Re-enumerate all host devices. */
-            drvAudioDevicesEnumerateInternal(pThis, true /* fLog */, NULL /* pDevEnum */);
-
-            pThis->fEnumerateDevices = false;
-        }
+            if (pThis->fEnumerateDevices)
+            {
+                /* Re-enumerate all host devices. */
+                drvAudioDevicesEnumerateInternal(pThis, true /* fLog */, NULL /* pDevEnum */);
+
+                pThis->fEnumerateDevices = false;
+            }
 #endif /* VBOX_WITH_AUDIO_ENUM */
 
-        /* Remove the pending re-init flag in any case, regardless whether the actual re-initialization succeeded
-         * or not. If it failed, the backend needs to notify us again to try again at some later point in time. */
-        pStream->fStatus &= ~PDMAUDIOSTREAMSTS_FLAGS_PENDING_REINIT;
-        rc = drvAudioStreamReInitInternal(pThis, pStream);
-    }
-
-    return rc;
+            int rc = drvAudioStreamReInitInternal(pThis, pStream);
+            if (RT_FAILURE(rc))
+            {
+                pStream->cTriesReInit++;
+                pStream->tsLastReInitNs = tsNowNs;
+            }
+            else
+            {
+                /* Remove the pending re-init flag on success. */
+                pStream->fStatus &= ~PDMAUDIOSTREAMSTS_FLAGS_PENDING_REINIT;
+            }
+        }
+        else
+        {
+            /* Did we exceed our tries re-initializing the stream?
+             * Then this one is dead-in-the-water, so disable it for further use. */
+            if (pStream->cTriesReInit == cMaxTries)
+            {
+                LogRel(("Audio: Re-initializing stream '%s' exceeded maximum retries (%u), leaving as disabled\n",
+                        pStream->szName, cMaxTries));
+
+                /* Don't try to re-initialize anymore and mark as disabled. */
+                pStream->fStatus &= ~(PDMAUDIOSTREAMSTS_FLAGS_PENDING_REINIT | PDMAUDIOSTREAMSTS_FLAGS_ENABLED);
+
+                /* Note: Further writes to this stream go to / will be read from the bit bucket (/dev/null) from now on. */
+            }
+        }
+
+#ifdef LOG_ENABLED
+        char *pszStreamSts = dbgAudioStreamStatusToStr(pStream->fStatus);
+        Log3Func(("[%s] fStatus=%s\n", pStream->szName, pszStreamSts));
+        RTStrFree(pszStreamSts);
+#endif /* LOG_ENABLED */
+
+    }
 }
 
@@ -1160,7 +1197,5 @@
 
     /* Is the stream scheduled for re-initialization? Do so now. */
-    int rc = drvAudioStreamMaybeReInit(pThis, pStream);
-    if (RT_FAILURE(rc))
-        return rc;
+    drvAudioStreamMaybeReInit(pThis, pStream);
 
 #ifdef LOG_ENABLED
@@ -1179,4 +1214,6 @@
     /* Whether to try closing a pending to close stream. */
     bool fTryClosePending = false;
+
+    int rc;
 
     do
@@ -2904,7 +2941,5 @@
 
     /* Is the stream scheduled for re-initialization? Do so now. */
-    int rc = drvAudioStreamMaybeReInit(pThis, pStream);
-    if (RT_FAILURE(rc)) /** @todo r=aeichner What is the correct operation in the failure case? */
-        LogRel(("Audio: Reinitializing the stream in drvAudioStreamGetStatus() failed with %Rrc\n", rc));
+    drvAudioStreamMaybeReInit(pThis, pStream);
 
     PDMAUDIOSTREAMSTS fStrmStatus = pStream->fStatus;
