Index: /trunk/src/VBox/Devices/Audio/DrvHostPulseAudio.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DrvHostPulseAudio.cpp	(revision 85345)
+++ /trunk/src/VBox/Devices/Audio/DrvHostPulseAudio.cpp	(revision 85346)
@@ -29,4 +29,5 @@
 #include <iprt/mem.h>
 #include <iprt/uuid.h>
+#include <iprt/semaphore.h>
 
 RT_C_DECLS_BEGIN
@@ -321,4 +322,29 @@
 
 /**
+ * Context status changed, init variant signalling our own event semaphore
+ * so we can do a timed wait.
+ */
+static void paContextCbStateChangedInit(pa_context *pCtx, void *pvUser)
+{
+    AssertPtrReturnVoid(pCtx);
+
+    RTSEMEVENT hEvtInit = (RTSEMEVENT)pvUser;
+    AssertReturnVoid(hEvtInit != NIL_RTSEMEVENT);
+
+    switch (pa_context_get_state(pCtx))
+    {
+        case PA_CONTEXT_READY:
+        case PA_CONTEXT_TERMINATED:
+        case PA_CONTEXT_FAILED:
+            RTSemEventSignal(hEvtInit);
+            break;
+
+        default:
+            break;
+    }
+}
+
+
+/**
  * Context status changed.
  */
@@ -660,38 +686,53 @@
             LogRel(("PulseAudio: Failed to start threaded mainloop: %s\n",
                      pa_strerror(pa_context_errno(pThis->pContext))));
-            break;
-        }
-
-        /* Install a global callback to known if something happens to our acquired context. */
-        pa_context_set_state_callback(pThis->pContext, paContextCbStateChanged, pThis /* pvUserData */);
+            rc = VERR_AUDIO_BACKEND_INIT_FAILED;
+            break;
+        }
+
+        RTSEMEVENT hEvtInit = NIL_RTSEMEVENT;
+        rc = RTSemEventCreate(&hEvtInit);
+        if (RT_FAILURE(rc))
+        {
+            LogRel(("PulseAudio: Failed to create init event semaphore: %Rrc\n", rc));
+            break;
+        }
+
+        /*
+         * Install a dedicated init state callback so we can do a timed wait on our own event semaphore if connecting
+         * to the pulseaudio server takes too long.
+         */
+        pa_context_set_state_callback(pThis->pContext, paContextCbStateChangedInit, hEvtInit /* pvUserData */);
 
         pa_threaded_mainloop_lock(pThis->pMainLoop);
         fLocked = true;
 
-        if (pa_context_connect(pThis->pContext, NULL /* pszServer */,
-                               PA_CONTEXT_NOFLAGS, NULL) < 0)
-        {
+        if (!pa_context_connect(pThis->pContext, NULL /* pszServer */,
+                                PA_CONTEXT_NOFLAGS, NULL))
+        {
+            /* Wait on our init event semaphore and time out if connecting to the pulseaudio server takes too long. */
+            pa_threaded_mainloop_unlock(pThis->pMainLoop);
+            fLocked = false;
+
+            rc = RTSemEventWait(hEvtInit, RT_MS_10SEC); /* 10 seconds should be plenty. */
+
+            pa_threaded_mainloop_lock(pThis->pMainLoop);
+            fLocked = true;
+
+            pa_context_state_t cstate = pa_context_get_state(pThis->pContext);
+            if (cstate != PA_CONTEXT_READY)
+            {
+                LogRel(("PulseAudio: Failed to initialize context (state %d, rc=%Rrc)\n", cstate, rc));
+                if (RT_SUCCESS(rc))
+                    rc = VERR_AUDIO_BACKEND_INIT_FAILED;
+            }
+        }
+        else
             LogRel(("PulseAudio: Failed to connect to server: %s\n",
                      pa_strerror(pa_context_errno(pThis->pContext))));
-            break;
-        }
-
-        /* Wait until the pThis->pContext is ready. */
-        for (;;)
-        {
-            if (!pThis->fAbortLoop)
-                pa_threaded_mainloop_wait(pThis->pMainLoop);
-            pThis->fAbortLoop = false;
-
-            pa_context_state_t cstate = pa_context_get_state(pThis->pContext);
-            if (cstate == PA_CONTEXT_READY)
-                break;
-            else if (   cstate == PA_CONTEXT_TERMINATED
-                     || cstate == PA_CONTEXT_FAILED)
-            {
-                LogRel(("PulseAudio: Failed to initialize context (state %d)\n", cstate));
-                break;
-            }
-        }
+
+        RTSemEventDestroy(hEvtInit);
+
+        /* Install the main state changed callback to know if something happens to our acquired context. */
+        pa_context_set_state_callback(pThis->pContext, paContextCbStateChanged, pThis /* pvUserData */);
     }
     while (0);
