VirtualBox

Changeset 70579 in vbox


Ignore:
Timestamp:
Jan 14, 2018 12:46:15 PM (7 years ago)
Author:
vboxsync
Message:

Main/AudioDriver: Fixed crash trying to configure device when no audio device is present. Deduplicated attach/deatch code spread around ConsoleImpl.cpp, putting it into two methods doAttachDriverViaEmt and doDetachDriverViaEmt.

Location:
trunk/src/VBox/Main
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/AudioDriver.h

    r70563 r70579  
    2121#include <VBox/com/ptr.h>
    2222#include <VBox/com/string.h>
     23#include <VBox/com/AutoLock.h>
    2324
    2425using namespace com;
     
    6162
    6263public:
    63 
    6464    AudioDriver(Console *pConsole);
    65 
    6665    virtual ~AudioDriver();
    67 
    68     AudioDriverCfg *GetConfig(void) { return &mCfg; }
    6966
    7067    Console *GetParent(void) { return mpConsole; }
    7168
    72     int Initialize(AudioDriverCfg *pCfg);
     69    AudioDriverCfg *GetConfig(void) { return &mCfg; }
     70    int InitializeConfig(AudioDriverCfg *pCfg);
     71
     72    /** Checks if audio is configured or not. */
     73    bool isConfigured() const { return mCfg.strName.isNotEmpty(); }
    7374
    7475    bool IsAttached(void) { return mfAttached; }
    7576
    76     static DECLCALLBACK(int) Attach(AudioDriver *pThis);
    77 
    78     static DECLCALLBACK(int) Detach(AudioDriver *pThis);
     77    int doAttachDriverViaEmt(PUVM pUVM, util::AutoWriteLock *pAutoLock);
     78    int doDetachDriverViaEmt(PUVM pUVM, util::AutoWriteLock *pAutoLock);
    7979
    8080protected:
     81    static DECLCALLBACK(int) attachDriverOnEmt(AudioDriver *pThis);
     82    static DECLCALLBACK(int) detachDriverOnEmt(AudioDriver *pThis);
    8183
    8284    int configure(unsigned uLUN, bool fAttach);
     
    106108};
    107109
    108 #endif /* ____H_AUDIODRIVER */
     110#endif /* !____H_AUDIODRIVER */
    109111
  • trunk/src/VBox/Main/src-client/AudioDriver.cpp

    r70564 r70579  
    7474/**
    7575 * Initializes the audio driver with a certain (device) configuration.
    76  * Note: The driver's LUN will be determined on runtime when attaching the
     76 *
     77 * @note The driver's LUN will be determined on runtime when attaching the
    7778 *       driver to the audio driver chain.
    7879 *
    7980 * @returns VBox status code.
    80  * @param pCfg                  Audio driver configuration to use.
    81  */
    82 int AudioDriver::Initialize(AudioDriverCfg *pCfg)
     81 * @param   pCfg                Audio driver configuration to use.
     82 */
     83int AudioDriver::InitializeConfig(AudioDriverCfg *pCfg)
    8384{
    8485    AssertPtrReturn(pCfg, VERR_INVALID_POINTER);
     
    9091}
    9192
     93
     94/**
     95 * Attaches the driver via EMT, if configured.
     96 *
     97 * @returns IPRT status code.
     98 * @param   pUVM                The user mode VM handle for talking to EMT.
     99 * @param   pAutoLock           The callers auto lock instance.  Can be NULL if
     100 *                              not locked.
     101 */
     102int AudioDriver::doAttachDriverViaEmt(PUVM pUVM, util::AutoWriteLock *pAutoLock)
     103{
     104    if (!isConfigured())
     105        return VINF_SUCCESS;
     106
     107    PVMREQ pReq;
     108    int vrc = VMR3ReqCallU(pUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
     109                           (PFNRT)attachDriverOnEmt, 1, this);
     110    if (vrc == VERR_TIMEOUT)
     111    {
     112        /* Release the lock before a blocking VMR3* call (EMT might wait for it, @bugref{7648})! */
     113        if (pAutoLock)
     114            pAutoLock->release();
     115
     116        vrc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
     117
     118        if (pAutoLock)
     119            pAutoLock->acquire();
     120    }
     121
     122    AssertRC(vrc);
     123    VMR3ReqFree(pReq);
     124
     125    return vrc;
     126}
     127
     128
    92129/**
    93130 * Configures the audio driver (to CFGM) and attaches it to the audio chain.
     
    98135 */
    99136/* static */
    100 DECLCALLBACK(int) AudioDriver::Attach(AudioDriver *pThis)
     137DECLCALLBACK(int) AudioDriver::attachDriverOnEmt(AudioDriver *pThis)
    101138{
    102139    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     
    105142    Assert(ptrVM.isOk());
    106143
    107     int vrc = VINF_SUCCESS;
    108144
    109145    if (pThis->mfAttached) /* Already attached? Bail out. */
     
    122158             pCfg->strName.c_str(), pCfg->strDev.c_str(), pCfg->uInst, uLUN));
    123159
    124     vrc = pThis->configure(uLUN, true /* Attach */);
     160    int vrc = pThis->configure(uLUN, true /* Attach */);
    125161    if (RT_SUCCESS(vrc))
    126162        vrc = PDMR3DeviceAttach(ptrVM.rawUVM(), pCfg->strDev.c_str(), pCfg->uInst, uLUN, 0 /* fFlags */,
     
    139175}
    140176
     177
     178/**
     179 * Detatches the driver via EMT, if configured.
     180 *
     181 * @returns IPRT status code.
     182 * @param   pUVM                The user mode VM handle for talking to EMT.
     183 * @param   pAutoLock           The callers auto lock instance.  Can be NULL if
     184 *                              not locked.
     185 */
     186int AudioDriver::doDetachDriverViaEmt(PUVM pUVM, util::AutoWriteLock *pAutoLock)
     187{
     188    if (!isConfigured())
     189        return VINF_SUCCESS;
     190
     191    PVMREQ pReq;
     192    int vrc = VMR3ReqCallU(pUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
     193                           (PFNRT)detachDriverOnEmt, 1, this);
     194    if (vrc == VERR_TIMEOUT)
     195    {
     196        /* Release the lock before a blocking VMR3* call (EMT might wait for it, @bugref{7648})! */
     197        if (pAutoLock)
     198            pAutoLock->release();
     199
     200        vrc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
     201
     202        if (pAutoLock)
     203            pAutoLock->acquire();
     204    }
     205
     206    AssertRC(vrc);
     207    VMR3ReqFree(pReq);
     208
     209    return vrc;
     210}
     211
     212
    141213/**
    142214 * Detaches an already attached audio driver from the audio chain.
     
    147219 */
    148220/* static */
    149 DECLCALLBACK(int) AudioDriver::Detach(AudioDriver *pThis)
     221DECLCALLBACK(int) AudioDriver::detachDriverOnEmt(AudioDriver *pThis)
    150222{
    151223    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r70565 r70579  
    54145414                            {
    54155415#ifdef VBOX_WITH_AUDIO_VRDE
    5416                                 alock.acquire();
    5417 
    5418                                 PVMREQ pReq;
    5419                                 int vrc2 = VMR3ReqCallU(mpUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
    5420                                                         (PFNRT)AudioVRDE::Attach, 1,
    5421                                                         mAudioVRDE);
    5422 
    5423                                 /* Release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
    5424                                 alock.release();
    5425 
    5426                                 if (vrc2 == VERR_TIMEOUT)
    5427                                     vrc2 = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
    5428                                 AssertRC(vrc2);
    5429                                 VMR3ReqFree(pReq);
     5416                                mAudioVRDE->doAttachDriverViaEmt(mpUVM, NULL /*alock is not held*/);
    54305417#endif
    54315418                                mConsoleVRDPServer->EnableConnections();
     
    54365423                            mConsoleVRDPServer->Stop();
    54375424#ifdef VBOX_WITH_AUDIO_VRDE
    5438                             alock.acquire();
    5439 
    5440                             PVMREQ pReq;
    5441                             int vrc2 = VMR3ReqCallU(mpUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
    5442                                                     (PFNRT)AudioVRDE::Detach, 1,
    5443                                                     mAudioVRDE);
    5444 
    5445                             /* Release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
    5446                             alock.release();
    5447 
    5448                             if (vrc2 == VERR_TIMEOUT)
    5449                                 vrc2 = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
    5450                             AssertRC(vrc2);
    5451                             VMR3ReqFree(pReq);
     5425                            mAudioVRDE->doDetachDriverViaEmt(mpUVM, NULL /*alock is not held*/);
    54525426#endif
    54535427                        }
     
    55535527                /* Attach the video recording audio driver if required. */
    55545528                if (mDisplay->i_videoRecGetEnabled() & VIDEORECFEATURE_AUDIO)
    5555                 {
    5556                     PVMREQ pReq;
    5557                     int vrc2 = VMR3ReqCallU(mpUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
    5558                                             (PFNRT)AudioVideoRec::Attach, 1,
    5559                                             mAudioVideoRec);
    5560 
    5561                     /* Release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
    5562                     alock.release();
    5563 
    5564                     if (vrc2 == VERR_TIMEOUT)
    5565                         vrc2 = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
    5566                     AssertRC(vrc2);
    5567                     VMR3ReqFree(pReq);
    5568 
    5569                     alock.acquire();
    5570                 }
     5529                    mAudioVideoRec->doAttachDriverViaEmt(mpUVM, &alock);
    55715530# endif
    55725531                vrc = mDisplay->i_videoRecStart();
     
    55785537                mDisplay->i_videoRecStop();
    55795538# ifdef VBOX_WITH_AUDIO_VIDEOREC
    5580                 PVMREQ pReq;
    5581                 int vrc2 = VMR3ReqCallU(mpUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
    5582                                         (PFNRT)AudioVideoRec::Detach, 1,
    5583                                         mAudioVideoRec);
    5584 
    5585                 /* Release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
    5586                 alock.release();
    5587 
    5588                 if (vrc2 == VERR_TIMEOUT)
    5589                     vrc2 = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
    5590                 AssertRC(vrc2);
    5591                 VMR3ReqFree(pReq);
    5592 
    5593                 alock.acquire();
     5539                mAudioVideoRec->doDetachDriverViaEmt(mpUVM, &alock);
    55945540# endif
    55955541            }
     
    98959841
    98969842            if (fVRDEEnabled)
    9897             {
    9898                 PVMREQ pReq;
    9899                 int vrc2 = VMR3ReqCallU(pConsole->mpUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
    9900                                         (PFNRT)AudioVRDE::Attach, 1,
    9901                                         pConsole->mAudioVRDE);
    9902 
    9903                 /* Release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
    9904                 alock.release();
    9905 
    9906                 if (vrc2 == VERR_TIMEOUT)
    9907                     vrc2 = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
    9908                 AssertRC(vrc2);
    9909                 VMR3ReqFree(pReq);
    9910 
    9911                 alock.acquire();
    9912             }
     9843                pConsole->mAudioVRDE->doAttachDriverViaEmt(pConsole->mpUVM, &alock);
    99139844        }
    99149845#endif
     
    99269857            /* Attach the video recording audio driver if required. */
    99279858            if (pDisplay->i_videoRecGetEnabled() & VIDEORECFEATURE_AUDIO)
    9928             {
    9929                 PVMREQ pReq;
    9930                 int vrc2 = VMR3ReqCallU(pConsole->mpUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
    9931                                         (PFNRT)AudioVideoRec::Attach, 1,
    9932                                         pConsole->mAudioVideoRec);
    9933 
    9934                 /* Release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
    9935                 alock.release();
    9936 
    9937                 if (vrc2 == VERR_TIMEOUT)
    9938                     vrc2 = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
    9939                 AssertRC(vrc2);
    9940                 VMR3ReqFree(pReq);
    9941 
    9942                 alock.acquire();
    9943             }
     9859                pConsole->mAudioVideoRec->doAttachDriverViaEmt(pConsole->mpUVM, &alock);
    99449860        }
    99459861#endif
  • trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp

    r70563 r70579  
    29712971#ifdef VBOX_WITH_AUDIO_VRDE
    29722972            AudioDriverCfg DrvCfgVRDE(strAudioDevice, 0 /* Instance */, "AudioVRDE");
    2973             rc = mAudioVRDE->Initialize(&DrvCfgVRDE);
     2973            rc = mAudioVRDE->InitializeConfig(&DrvCfgVRDE);
    29742974            AssertRC(rc);
    29752975#endif /* VBOX_WITH_AUDIO_VRDE */
     
    29772977#ifdef VBOX_WITH_AUDIO_VIDEOREC
    29782978            AudioDriverCfg DrvCfgVideoRec(strAudioDevice, 0 /* Instance */, "AudioVideoRec");
    2979             rc = mAudioVideoRec->Initialize(&DrvCfgVideoRec);
     2979            rc = mAudioVideoRec->InitializeConfig(&DrvCfgVideoRec);
    29802980            AssertRC(rc);
    29812981#endif /* VBOX_WITH_AUDIO_VIDEOREC */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette