Index: /trunk/src/VBox/Devices/Audio/DrvHostPulseAudio.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DrvHostPulseAudio.cpp	(revision 58581)
+++ /trunk/src/VBox/Devices/Audio/DrvHostPulseAudio.cpp	(revision 58582)
@@ -58,4 +58,5 @@
 static struct pa_threaded_mainloop *g_pMainLoop;
 static struct pa_context           *g_pContext;
+static volatile bool                g_fAbortMainLoop;
 
 /**
@@ -130,4 +131,14 @@
 static void drvHostPulseAudioCbSuccess(pa_stream *pStream, int fSuccess, void *pvContext);
 
+/**
+ * Signal the main loop to abort. Just signalling isn't sufficient as the
+ * mainloop might not have been entered yet.
+ */
+static void drvHostPulseAudioAbortMainLoop(void)
+{
+    g_fAbortMainLoop = true;
+    pa_threaded_mainloop_signal(g_pMainLoop, 0);
+}
+
 static pa_sample_format_t drvHostPulseAudioFmtToPulse(PDMAUDIOFMT fmt)
 {
@@ -228,10 +239,8 @@
  * Context status changed.
  */
-static void drvHostPulseAudioCbCtxState(pa_context *pContext, void *pvContext)
+static void drvHostPulseAudioCbCtxState(pa_context *pContext, void *pvUser)
 {
     AssertPtrReturnVoid(pContext);
-
-    PPULSEAUDIOSTREAM pStrm = (PPULSEAUDIOSTREAM)pvContext;
-    NOREF(pStrm);
+    NOREF(pvUser);
 
     switch (pa_context_get_state(pContext))
@@ -239,10 +248,10 @@
         case PA_CONTEXT_READY:
         case PA_CONTEXT_TERMINATED:
-            pa_threaded_mainloop_signal(g_pMainLoop, 0);
+            drvHostPulseAudioAbortMainLoop();
             break;
 
         case PA_CONTEXT_FAILED:
             LogRel(("PulseAudio: Audio input/output stopped!\n"));
-            pa_threaded_mainloop_signal(g_pMainLoop, 0);
+            drvHostPulseAudioAbortMainLoop();
             break;
 
@@ -288,5 +297,5 @@
         case PA_STREAM_FAILED:
         case PA_STREAM_TERMINATED:
-            pa_threaded_mainloop_signal(g_pMainLoop, 0 /* fWait */);
+            drvHostPulseAudioAbortMainLoop();
             break;
 
@@ -306,7 +315,5 @@
 
     if (fSuccess)
-    {
-        pa_threaded_mainloop_signal(g_pMainLoop, 0 /* fWait */);
-    }
+        drvHostPulseAudioAbortMainLoop();
     else
          drvHostPulseAudioError(pStrm->pDrv, "Failed to finish stream operation");
@@ -396,5 +403,6 @@
         for (;;)
         {
-            pa_threaded_mainloop_wait(g_pMainLoop);
+            if (!g_fAbortMainLoop)
+                pa_threaded_mainloop_wait(g_pMainLoop);
 
             sstate = pa_stream_get_state(pStream);
@@ -487,4 +495,5 @@
         }
 
+        g_fAbortMainLoop = false;
         pa_context_set_state_callback(g_pContext, drvHostPulseAudioCbCtxState, NULL);
         pa_threaded_mainloop_lock(g_pMainLoop);
@@ -504,5 +513,6 @@
         {
             pa_context_state_t cstate;
-            pa_threaded_mainloop_wait(g_pMainLoop);
+            if (!g_fAbortMainLoop)
+                pa_threaded_mainloop_wait(g_pMainLoop);
 
             cstate = pa_context_get_state(g_pContext);
@@ -517,19 +527,14 @@
             }
         }
-
+    }
+    while (0);
+
+    if (fLocked)
         pa_threaded_mainloop_unlock(g_pMainLoop);
-    }
-    while (0);
 
     if (RT_FAILURE(rc))
     {
         if (g_pMainLoop)
-        {
-            if (fLocked)
-                pa_threaded_mainloop_unlock(g_pMainLoop);
-
-            if (g_pMainLoop)
-                pa_threaded_mainloop_stop(g_pMainLoop);
-        }
+            pa_threaded_mainloop_stop(g_pMainLoop);
 
         if (g_pContext)
