Index: /trunk/src/VBox/Main/include/AudioDriver.h
===================================================================
--- /trunk/src/VBox/Main/include/AudioDriver.h	(revision 70578)
+++ /trunk/src/VBox/Main/include/AudioDriver.h	(revision 70579)
@@ -21,4 +21,5 @@
 #include <VBox/com/ptr.h>
 #include <VBox/com/string.h>
+#include <VBox/com/AutoLock.h>
 
 using namespace com;
@@ -61,22 +62,23 @@
 
 public:
-
     AudioDriver(Console *pConsole);
-
     virtual ~AudioDriver();
-
-    AudioDriverCfg *GetConfig(void) { return &mCfg; }
 
     Console *GetParent(void) { return mpConsole; }
 
-    int Initialize(AudioDriverCfg *pCfg);
+    AudioDriverCfg *GetConfig(void) { return &mCfg; }
+    int InitializeConfig(AudioDriverCfg *pCfg);
+
+    /** Checks if audio is configured or not. */
+    bool isConfigured() const { return mCfg.strName.isNotEmpty(); }
 
     bool IsAttached(void) { return mfAttached; }
 
-    static DECLCALLBACK(int) Attach(AudioDriver *pThis);
-
-    static DECLCALLBACK(int) Detach(AudioDriver *pThis);
+    int doAttachDriverViaEmt(PUVM pUVM, util::AutoWriteLock *pAutoLock);
+    int doDetachDriverViaEmt(PUVM pUVM, util::AutoWriteLock *pAutoLock);
 
 protected:
+    static DECLCALLBACK(int) attachDriverOnEmt(AudioDriver *pThis);
+    static DECLCALLBACK(int) detachDriverOnEmt(AudioDriver *pThis);
 
     int configure(unsigned uLUN, bool fAttach);
@@ -106,4 +108,4 @@
 };
 
-#endif /* ____H_AUDIODRIVER */
+#endif /* !____H_AUDIODRIVER */
 
Index: /trunk/src/VBox/Main/src-client/AudioDriver.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/AudioDriver.cpp	(revision 70578)
+++ /trunk/src/VBox/Main/src-client/AudioDriver.cpp	(revision 70579)
@@ -74,11 +74,12 @@
 /**
  * Initializes the audio driver with a certain (device) configuration.
- * Note: The driver's LUN will be determined on runtime when attaching the
+ *
+ * @note The driver's LUN will be determined on runtime when attaching the
  *       driver to the audio driver chain.
  *
  * @returns VBox status code.
- * @param pCfg                  Audio driver configuration to use.
- */
-int AudioDriver::Initialize(AudioDriverCfg *pCfg)
+ * @param   pCfg                Audio driver configuration to use.
+ */
+int AudioDriver::InitializeConfig(AudioDriverCfg *pCfg)
 {
     AssertPtrReturn(pCfg, VERR_INVALID_POINTER);
@@ -90,4 +91,40 @@
 }
 
+
+/**
+ * Attaches the driver via EMT, if configured.
+ *
+ * @returns IPRT status code.
+ * @param   pUVM                The user mode VM handle for talking to EMT.
+ * @param   pAutoLock           The callers auto lock instance.  Can be NULL if
+ *                              not locked.
+ */
+int AudioDriver::doAttachDriverViaEmt(PUVM pUVM, util::AutoWriteLock *pAutoLock)
+{
+    if (!isConfigured())
+        return VINF_SUCCESS;
+
+    PVMREQ pReq;
+    int vrc = VMR3ReqCallU(pUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
+                           (PFNRT)attachDriverOnEmt, 1, this);
+    if (vrc == VERR_TIMEOUT)
+    {
+        /* Release the lock before a blocking VMR3* call (EMT might wait for it, @bugref{7648})! */
+        if (pAutoLock)
+            pAutoLock->release();
+
+        vrc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
+
+        if (pAutoLock)
+            pAutoLock->acquire();
+    }
+
+    AssertRC(vrc);
+    VMR3ReqFree(pReq);
+
+    return vrc;
+}
+
+
 /**
  * Configures the audio driver (to CFGM) and attaches it to the audio chain.
@@ -98,5 +135,5 @@
  */
 /* static */
-DECLCALLBACK(int) AudioDriver::Attach(AudioDriver *pThis)
+DECLCALLBACK(int) AudioDriver::attachDriverOnEmt(AudioDriver *pThis)
 {
     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
@@ -105,5 +142,4 @@
     Assert(ptrVM.isOk());
 
-    int vrc = VINF_SUCCESS;
 
     if (pThis->mfAttached) /* Already attached? Bail out. */
@@ -122,5 +158,5 @@
              pCfg->strName.c_str(), pCfg->strDev.c_str(), pCfg->uInst, uLUN));
 
-    vrc = pThis->configure(uLUN, true /* Attach */);
+    int vrc = pThis->configure(uLUN, true /* Attach */);
     if (RT_SUCCESS(vrc))
         vrc = PDMR3DeviceAttach(ptrVM.rawUVM(), pCfg->strDev.c_str(), pCfg->uInst, uLUN, 0 /* fFlags */,
@@ -139,4 +175,40 @@
 }
 
+
+/**
+ * Detatches the driver via EMT, if configured.
+ *
+ * @returns IPRT status code.
+ * @param   pUVM                The user mode VM handle for talking to EMT.
+ * @param   pAutoLock           The callers auto lock instance.  Can be NULL if
+ *                              not locked.
+ */
+int AudioDriver::doDetachDriverViaEmt(PUVM pUVM, util::AutoWriteLock *pAutoLock)
+{
+    if (!isConfigured())
+        return VINF_SUCCESS;
+
+    PVMREQ pReq;
+    int vrc = VMR3ReqCallU(pUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
+                           (PFNRT)detachDriverOnEmt, 1, this);
+    if (vrc == VERR_TIMEOUT)
+    {
+        /* Release the lock before a blocking VMR3* call (EMT might wait for it, @bugref{7648})! */
+        if (pAutoLock)
+            pAutoLock->release();
+
+        vrc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
+
+        if (pAutoLock)
+            pAutoLock->acquire();
+    }
+
+    AssertRC(vrc);
+    VMR3ReqFree(pReq);
+
+    return vrc;
+}
+
+
 /**
  * Detaches an already attached audio driver from the audio chain.
@@ -147,5 +219,5 @@
  */
 /* static */
-DECLCALLBACK(int) AudioDriver::Detach(AudioDriver *pThis)
+DECLCALLBACK(int) AudioDriver::detachDriverOnEmt(AudioDriver *pThis)
 {
     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
Index: /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 70578)
+++ /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 70579)
@@ -5414,18 +5414,5 @@
                             {
 #ifdef VBOX_WITH_AUDIO_VRDE
-                                alock.acquire();
-
-                                PVMREQ pReq;
-                                int vrc2 = VMR3ReqCallU(mpUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
-                                                        (PFNRT)AudioVRDE::Attach, 1,
-                                                        mAudioVRDE);
-
-                                /* Release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
-                                alock.release();
-
-                                if (vrc2 == VERR_TIMEOUT)
-                                    vrc2 = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
-                                AssertRC(vrc2);
-                                VMR3ReqFree(pReq);
+                                mAudioVRDE->doAttachDriverViaEmt(mpUVM, NULL /*alock is not held*/);
 #endif
                                 mConsoleVRDPServer->EnableConnections();
@@ -5436,18 +5423,5 @@
                             mConsoleVRDPServer->Stop();
 #ifdef VBOX_WITH_AUDIO_VRDE
-                            alock.acquire();
-
-                            PVMREQ pReq;
-                            int vrc2 = VMR3ReqCallU(mpUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
-                                                    (PFNRT)AudioVRDE::Detach, 1,
-                                                    mAudioVRDE);
-
-                            /* Release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
-                            alock.release();
-
-                            if (vrc2 == VERR_TIMEOUT)
-                                vrc2 = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
-                            AssertRC(vrc2);
-                            VMR3ReqFree(pReq);
+                            mAudioVRDE->doDetachDriverViaEmt(mpUVM, NULL /*alock is not held*/);
 #endif
                         }
@@ -5553,20 +5527,5 @@
                 /* Attach the video recording audio driver if required. */
                 if (mDisplay->i_videoRecGetEnabled() & VIDEORECFEATURE_AUDIO)
-                {
-                    PVMREQ pReq;
-                    int vrc2 = VMR3ReqCallU(mpUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
-                                            (PFNRT)AudioVideoRec::Attach, 1,
-                                            mAudioVideoRec);
-
-                    /* Release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
-                    alock.release();
-
-                    if (vrc2 == VERR_TIMEOUT)
-                        vrc2 = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
-                    AssertRC(vrc2);
-                    VMR3ReqFree(pReq);
-
-                    alock.acquire();
-                }
+                    mAudioVideoRec->doAttachDriverViaEmt(mpUVM, &alock);
 # endif
                 vrc = mDisplay->i_videoRecStart();
@@ -5578,18 +5537,5 @@
                 mDisplay->i_videoRecStop();
 # ifdef VBOX_WITH_AUDIO_VIDEOREC
-                PVMREQ pReq;
-                int vrc2 = VMR3ReqCallU(mpUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
-                                        (PFNRT)AudioVideoRec::Detach, 1,
-                                        mAudioVideoRec);
-
-                /* Release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
-                alock.release();
-
-                if (vrc2 == VERR_TIMEOUT)
-                    vrc2 = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
-                AssertRC(vrc2);
-                VMR3ReqFree(pReq);
-
-                alock.acquire();
+                mAudioVideoRec->doDetachDriverViaEmt(mpUVM, &alock);
 # endif
             }
@@ -9895,20 +9841,5 @@
 
             if (fVRDEEnabled)
-            {
-                PVMREQ pReq;
-                int vrc2 = VMR3ReqCallU(pConsole->mpUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
-                                        (PFNRT)AudioVRDE::Attach, 1,
-                                        pConsole->mAudioVRDE);
-
-                /* Release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
-                alock.release();
-
-                if (vrc2 == VERR_TIMEOUT)
-                    vrc2 = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
-                AssertRC(vrc2);
-                VMR3ReqFree(pReq);
-
-                alock.acquire();
-            }
+                pConsole->mAudioVRDE->doAttachDriverViaEmt(pConsole->mpUVM, &alock);
         }
 #endif
@@ -9926,20 +9857,5 @@
             /* Attach the video recording audio driver if required. */
             if (pDisplay->i_videoRecGetEnabled() & VIDEORECFEATURE_AUDIO)
-            {
-                PVMREQ pReq;
-                int vrc2 = VMR3ReqCallU(pConsole->mpUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
-                                        (PFNRT)AudioVideoRec::Attach, 1,
-                                        pConsole->mAudioVideoRec);
-
-                /* Release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
-                alock.release();
-
-                if (vrc2 == VERR_TIMEOUT)
-                    vrc2 = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
-                AssertRC(vrc2);
-                VMR3ReqFree(pReq);
-
-                alock.acquire();
-            }
+                pConsole->mAudioVideoRec->doAttachDriverViaEmt(pConsole->mpUVM, &alock);
         }
 #endif
Index: /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 70578)
+++ /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 70579)
@@ -2971,5 +2971,5 @@
 #ifdef VBOX_WITH_AUDIO_VRDE
             AudioDriverCfg DrvCfgVRDE(strAudioDevice, 0 /* Instance */, "AudioVRDE");
-            rc = mAudioVRDE->Initialize(&DrvCfgVRDE);
+            rc = mAudioVRDE->InitializeConfig(&DrvCfgVRDE);
             AssertRC(rc);
 #endif /* VBOX_WITH_AUDIO_VRDE */
@@ -2977,5 +2977,5 @@
 #ifdef VBOX_WITH_AUDIO_VIDEOREC
             AudioDriverCfg DrvCfgVideoRec(strAudioDevice, 0 /* Instance */, "AudioVideoRec");
-            rc = mAudioVideoRec->Initialize(&DrvCfgVideoRec);
+            rc = mAudioVideoRec->InitializeConfig(&DrvCfgVideoRec);
             AssertRC(rc);
 #endif /* VBOX_WITH_AUDIO_VIDEOREC */
