VirtualBox

Changeset 88213 in vbox


Ignore:
Timestamp:
Mar 19, 2021 6:13:35 PM (4 years ago)
Author:
vboxsync
Message:

DrvAudio: Put the basic driver function in more correct order. bugref:9890

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/DrvAudio.cpp

    r88181 r88213  
    34643464}
    34653465
     3466
     3467/*********************************************************************************************************************************
     3468*   PDMIBASE interface implementation.                                                                                           *
     3469*********************************************************************************************************************************/
     3470
     3471/**
     3472 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
     3473 */
     3474static DECLCALLBACK(void *) drvAudioQueryInterface(PPDMIBASE pInterface, const char *pszIID)
     3475{
     3476    LogFlowFunc(("pInterface=%p, pszIID=%s\n", pInterface, pszIID));
     3477
     3478    PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
     3479    PDRVAUDIO  pThis   = PDMINS_2_DATA(pDrvIns, PDRVAUDIO);
     3480
     3481    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
     3482    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIAUDIOCONNECTOR, &pThis->IAudioConnector);
     3483
     3484    return NULL;
     3485}
     3486
     3487
     3488/*********************************************************************************************************************************
     3489*   PDMDRVREG interface implementation.                                                                                          *
     3490*********************************************************************************************************************************/
     3491
     3492/**
     3493 * Power Off notification.
     3494 *
     3495 * @param   pDrvIns     The driver instance data.
     3496 */
     3497static DECLCALLBACK(void) drvAudioPowerOff(PPDMDRVINS pDrvIns)
     3498{
     3499    PDRVAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIO);
     3500
     3501    LogFlowFuncEnter();
     3502
     3503    if (!pThis->pHostDrvAudio) /* If not lower driver is configured, bail out. */
     3504        return;
     3505
     3506    /* Just destroy the host stream on the backend side.
     3507     * The rest will either be destructed by the device emulation or
     3508     * in drvAudioDestruct(). */
     3509    PPDMAUDIOSTREAM pStream;
     3510    RTListForEach(&pThis->lstStreams, pStream, PDMAUDIOSTREAM, ListEntry)
     3511    {
     3512        drvAudioStreamControlInternalBackend(pThis, pStream, PDMAUDIOSTREAMCMD_DISABLE);
     3513        drvAudioStreamDestroyInternalBackend(pThis, pStream);
     3514    }
     3515
     3516    /*
     3517     * Last call for the driver below us.
     3518     * Let it know that we reached end of life.
     3519     */
     3520    if (pThis->pHostDrvAudio->pfnShutdown)
     3521        pThis->pHostDrvAudio->pfnShutdown(pThis->pHostDrvAudio);
     3522
     3523    pThis->pHostDrvAudio = NULL;
     3524
     3525    LogFlowFuncLeave();
     3526}
     3527
     3528
     3529/**
     3530 * Detach notification.
     3531 *
     3532 * @param   pDrvIns     The driver instance data.
     3533 * @param   fFlags      Detach flags.
     3534 */
     3535static DECLCALLBACK(void) drvAudioDetach(PPDMDRVINS pDrvIns, uint32_t fFlags)
     3536{
     3537    RT_NOREF(fFlags);
     3538
     3539    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
     3540    PDRVAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIO);
     3541
     3542    int rc2 = RTCritSectEnter(&pThis->CritSect);
     3543    AssertRC(rc2);
     3544
     3545    pThis->pHostDrvAudio = NULL;
     3546
     3547    LogFunc(("%s\n", pThis->szName));
     3548
     3549    rc2 = RTCritSectLeave(&pThis->CritSect);
     3550    AssertRC(rc2);
     3551}
     3552
     3553
    34663554/**
    34673555 * Does the actual backend driver attaching and queries the backend's interface.
     3556 *
     3557 * This is a worker for both drvAudioAttach and drvAudioConstruct.
    34683558 *
    34693559 * @return VBox status code.
     
    35053595
    35063596
    3507 /********************************************************************/
    3508 
    3509 /**
    3510  * @interface_method_impl{PDMIBASE,pfnQueryInterface}
    3511  */
    3512 static DECLCALLBACK(void *) drvAudioQueryInterface(PPDMIBASE pInterface, const char *pszIID)
    3513 {
    3514     LogFlowFunc(("pInterface=%p, pszIID=%s\n", pInterface, pszIID));
    3515 
    3516     PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
    3517     PDRVAUDIO  pThis   = PDMINS_2_DATA(pDrvIns, PDRVAUDIO);
    3518 
    3519     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
    3520     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIAUDIOCONNECTOR, &pThis->IAudioConnector);
    3521 
    3522     return NULL;
    3523 }
    3524 
    3525 /**
    3526  * Power Off notification.
     3597/**
     3598 * Attach notification.
    35273599 *
    35283600 * @param   pDrvIns     The driver instance data.
    3529  */
    3530 static DECLCALLBACK(void) drvAudioPowerOff(PPDMDRVINS pDrvIns)
    3531 {
     3601 * @param   fFlags      Attach flags.
     3602 */
     3603static DECLCALLBACK(int) drvAudioAttach(PPDMDRVINS pDrvIns, uint32_t fFlags)
     3604{
     3605    RT_NOREF(fFlags);
     3606
     3607    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    35323608    PDRVAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIO);
    35333609
     3610    int rc2 = RTCritSectEnter(&pThis->CritSect);
     3611    AssertRC(rc2);
     3612
     3613    LogFunc(("%s\n", pThis->szName));
     3614
     3615    int rc = drvAudioDoAttachInternal(pThis, fFlags);
     3616
     3617    rc2 = RTCritSectLeave(&pThis->CritSect);
     3618    if (RT_SUCCESS(rc))
     3619        rc = rc2;
     3620
     3621    return rc;
     3622}
     3623
     3624
     3625/**
     3626 * Resume notification.
     3627 *
     3628 * @param   pDrvIns     The driver instance data.
     3629 */
     3630static DECLCALLBACK(void) drvAudioResume(PPDMDRVINS pDrvIns)
     3631{
     3632    drvAudioStateHandler(pDrvIns, PDMAUDIOSTREAMCMD_RESUME);
     3633}
     3634
     3635
     3636/**
     3637 * Suspend notification.
     3638 *
     3639 * @param   pDrvIns     The driver instance data.
     3640 */
     3641static DECLCALLBACK(void) drvAudioSuspend(PPDMDRVINS pDrvIns)
     3642{
     3643    drvAudioStateHandler(pDrvIns, PDMAUDIOSTREAMCMD_PAUSE);
     3644}
     3645
     3646
     3647/**
     3648 * Destructs an audio driver instance.
     3649 *
     3650 * @copydoc FNPDMDRVDESTRUCT
     3651 */
     3652static DECLCALLBACK(void) drvAudioDestruct(PPDMDRVINS pDrvIns)
     3653{
     3654    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
     3655    PDRVAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIO);
     3656
    35343657    LogFlowFuncEnter();
    35353658
    3536     if (!pThis->pHostDrvAudio) /* If not lower driver is configured, bail out. */
    3537         return;
    3538 
    3539     /* Just destroy the host stream on the backend side.
    3540      * The rest will either be destructed by the device emulation or
    3541      * in drvAudioDestruct(). */
    3542     PPDMAUDIOSTREAM pStream;
    3543     RTListForEach(&pThis->lstStreams, pStream, PDMAUDIOSTREAM, ListEntry)
    3544     {
    3545         drvAudioStreamControlInternalBackend(pThis, pStream, PDMAUDIOSTREAMCMD_DISABLE);
    3546         drvAudioStreamDestroyInternalBackend(pThis, pStream);
     3659    int rc2;
     3660
     3661    if (RTCritSectIsInitialized(&pThis->CritSect))
     3662    {
     3663        rc2 = RTCritSectEnter(&pThis->CritSect);
     3664        AssertRC(rc2);
    35473665    }
    35483666
    35493667    /*
    3550      * Last call for the driver below us.
    3551      * Let it know that we reached end of life.
     3668     * Note: No calls here to the driver below us anymore,
     3669     *       as PDM already has destroyed it.
     3670     *       If you need to call something from the host driver,
     3671     *       do this in drvAudioPowerOff() instead.
    35523672     */
    3553     if (pThis->pHostDrvAudio->pfnShutdown)
    3554         pThis->pHostDrvAudio->pfnShutdown(pThis->pHostDrvAudio);
    3555 
     3673
     3674    /* Thus, NULL the pointer to the host audio driver first,
     3675     * so that routines like drvAudioStreamDestroyInternal() don't call the driver(s) below us anymore. */
    35563676    pThis->pHostDrvAudio = NULL;
    35573677
     3678    PPDMAUDIOSTREAM pStream, pStreamNext;
     3679    RTListForEachSafe(&pThis->lstStreams, pStream, pStreamNext, PDMAUDIOSTREAM, ListEntry)
     3680    {
     3681        rc2 = drvAudioStreamUninitInternal(pThis, pStream);
     3682        if (RT_SUCCESS(rc2))
     3683        {
     3684            RTListNodeRemove(&pStream->ListEntry);
     3685
     3686            drvAudioStreamFree(pStream);
     3687            pStream = NULL;
     3688        }
     3689    }
     3690
     3691    /* Sanity. */
     3692    Assert(RTListIsEmpty(&pThis->lstStreams));
     3693
     3694#ifdef VBOX_WITH_AUDIO_CALLBACKS
     3695    /*
     3696     * Destroy callbacks, if any.
     3697     */
     3698    PPDMAUDIOCBRECORD pCB, pCBNext;
     3699    RTListForEachSafe(&pThis->In.lstCB, pCB, pCBNext, PDMAUDIOCBRECORD, Node)
     3700        drvAudioCallbackDestroy(pCB);
     3701
     3702    RTListForEachSafe(&pThis->Out.lstCB, pCB, pCBNext, PDMAUDIOCBRECORD, Node)
     3703        drvAudioCallbackDestroy(pCB);
     3704#endif
     3705
     3706    if (pThis->pvScratchBuf)
     3707    {
     3708        Assert(pThis->cbScratchBuf);
     3709
     3710        RTMemFree(pThis->pvScratchBuf);
     3711        pThis->pvScratchBuf = NULL;
     3712    }
     3713
     3714    if (RTCritSectIsInitialized(&pThis->CritSect))
     3715    {
     3716        rc2 = RTCritSectLeave(&pThis->CritSect);
     3717        AssertRC(rc2);
     3718
     3719        rc2 = RTCritSectDelete(&pThis->CritSect);
     3720        AssertRC(rc2);
     3721    }
     3722
     3723#ifdef VBOX_WITH_STATISTICS
     3724    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalStreamsActive);
     3725    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalStreamsCreated);
     3726    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalFramesRead);
     3727    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalFramesWritten);
     3728    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalFramesMixedIn);
     3729    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalFramesMixedOut);
     3730    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalFramesLostIn);
     3731    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalFramesLostOut);
     3732    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalFramesOut);
     3733    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalFramesIn);
     3734    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalBytesRead);
     3735    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalBytesWritten);
     3736    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.DelayIn);
     3737    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.DelayOut);
     3738#endif
     3739
    35583740    LogFlowFuncLeave();
    35593741}
    35603742
     3743
    35613744/**
    35623745 * Constructs an audio driver instance.
     
    35663749static DECLCALLBACK(int) drvAudioConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
    35673750{
     3751    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
     3752    PDRVAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIO);
    35683753    LogFlowFunc(("pDrvIns=%#p, pCfgHandle=%#p, fFlags=%x\n", pDrvIns, pCfg, fFlags));
    35693754
    3570     PDRVAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIO);
    3571     PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    3572 
     3755    /*
     3756     * Basic instance init.
     3757     */
    35733758    RTListInit(&pThis->lstStreams);
    35743759#ifdef VBOX_WITH_AUDIO_CALLBACKS
     
    35773762#endif
    35783763
    3579     /*
    3580      * Init the static parts.
    3581      */
    35823764    pThis->pDrvIns                              = pDrvIns;
    35833765    /* IBase. */
     
    36423824    }
    36433825
     3826    /** @todo r=bird: you're overwriting rc here. sigh.  Just return immediately on
     3827     *        failure, don't try make it to the end of the function! GRRR! */
    36443828    rc = drvAudioDoAttachInternal(pThis, fFlags);
    36453829    if (RT_FAILURE(rc))
     
    36523836    LogFlowFuncLeaveRC(rc);
    36533837    return rc;
    3654 }
    3655 
    3656 /**
    3657  * Destructs an audio driver instance.
    3658  *
    3659  * @copydoc FNPDMDRVDESTRUCT
    3660  */
    3661 static DECLCALLBACK(void) drvAudioDestruct(PPDMDRVINS pDrvIns)
    3662 {
    3663     PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    3664     PDRVAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIO);
    3665 
    3666     LogFlowFuncEnter();
    3667 
    3668     int rc2;
    3669 
    3670     if (RTCritSectIsInitialized(&pThis->CritSect))
    3671     {
    3672         rc2 = RTCritSectEnter(&pThis->CritSect);
    3673         AssertRC(rc2);
    3674     }
    3675 
    3676     /*
    3677      * Note: No calls here to the driver below us anymore,
    3678      *       as PDM already has destroyed it.
    3679      *       If you need to call something from the host driver,
    3680      *       do this in drvAudioPowerOff() instead.
    3681      */
    3682 
    3683     /* Thus, NULL the pointer to the host audio driver first,
    3684      * so that routines like drvAudioStreamDestroyInternal() don't call the driver(s) below us anymore. */
    3685     pThis->pHostDrvAudio = NULL;
    3686 
    3687     PPDMAUDIOSTREAM pStream, pStreamNext;
    3688     RTListForEachSafe(&pThis->lstStreams, pStream, pStreamNext, PDMAUDIOSTREAM, ListEntry)
    3689     {
    3690         rc2 = drvAudioStreamUninitInternal(pThis, pStream);
    3691         if (RT_SUCCESS(rc2))
    3692         {
    3693             RTListNodeRemove(&pStream->ListEntry);
    3694 
    3695             drvAudioStreamFree(pStream);
    3696             pStream = NULL;
    3697         }
    3698     }
    3699 
    3700     /* Sanity. */
    3701     Assert(RTListIsEmpty(&pThis->lstStreams));
    3702 
    3703 #ifdef VBOX_WITH_AUDIO_CALLBACKS
    3704     /*
    3705      * Destroy callbacks, if any.
    3706      */
    3707     PPDMAUDIOCBRECORD pCB, pCBNext;
    3708     RTListForEachSafe(&pThis->In.lstCB, pCB, pCBNext, PDMAUDIOCBRECORD, Node)
    3709         drvAudioCallbackDestroy(pCB);
    3710 
    3711     RTListForEachSafe(&pThis->Out.lstCB, pCB, pCBNext, PDMAUDIOCBRECORD, Node)
    3712         drvAudioCallbackDestroy(pCB);
    3713 #endif
    3714 
    3715     if (pThis->pvScratchBuf)
    3716     {
    3717         Assert(pThis->cbScratchBuf);
    3718 
    3719         RTMemFree(pThis->pvScratchBuf);
    3720         pThis->pvScratchBuf = NULL;
    3721     }
    3722 
    3723     if (RTCritSectIsInitialized(&pThis->CritSect))
    3724     {
    3725         rc2 = RTCritSectLeave(&pThis->CritSect);
    3726         AssertRC(rc2);
    3727 
    3728         rc2 = RTCritSectDelete(&pThis->CritSect);
    3729         AssertRC(rc2);
    3730     }
    3731 
    3732 #ifdef VBOX_WITH_STATISTICS
    3733     PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalStreamsActive);
    3734     PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalStreamsCreated);
    3735     PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalFramesRead);
    3736     PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalFramesWritten);
    3737     PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalFramesMixedIn);
    3738     PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalFramesMixedOut);
    3739     PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalFramesLostIn);
    3740     PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalFramesLostOut);
    3741     PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalFramesOut);
    3742     PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalFramesIn);
    3743     PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalBytesRead);
    3744     PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalBytesWritten);
    3745     PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.DelayIn);
    3746     PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.DelayOut);
    3747 #endif
    3748 
    3749     LogFlowFuncLeave();
    3750 }
    3751 
    3752 /**
    3753  * Suspend notification.
    3754  *
    3755  * @param   pDrvIns     The driver instance data.
    3756  */
    3757 static DECLCALLBACK(void) drvAudioSuspend(PPDMDRVINS pDrvIns)
    3758 {
    3759     drvAudioStateHandler(pDrvIns, PDMAUDIOSTREAMCMD_PAUSE);
    3760 }
    3761 
    3762 /**
    3763  * Resume notification.
    3764  *
    3765  * @param   pDrvIns     The driver instance data.
    3766  */
    3767 static DECLCALLBACK(void) drvAudioResume(PPDMDRVINS pDrvIns)
    3768 {
    3769     drvAudioStateHandler(pDrvIns, PDMAUDIOSTREAMCMD_RESUME);
    3770 }
    3771 
    3772 /**
    3773  * Attach notification.
    3774  *
    3775  * @param   pDrvIns     The driver instance data.
    3776  * @param   fFlags      Attach flags.
    3777  */
    3778 static DECLCALLBACK(int) drvAudioAttach(PPDMDRVINS pDrvIns, uint32_t fFlags)
    3779 {
    3780     RT_NOREF(fFlags);
    3781 
    3782     PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    3783     PDRVAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIO);
    3784 
    3785     int rc2 = RTCritSectEnter(&pThis->CritSect);
    3786     AssertRC(rc2);
    3787 
    3788     LogFunc(("%s\n", pThis->szName));
    3789 
    3790     int rc = drvAudioDoAttachInternal(pThis, fFlags);
    3791 
    3792     rc2 = RTCritSectLeave(&pThis->CritSect);
    3793     if (RT_SUCCESS(rc))
    3794         rc = rc2;
    3795 
    3796     return rc;
    3797 }
    3798 
    3799 /**
    3800  * Detach notification.
    3801  *
    3802  * @param   pDrvIns     The driver instance data.
    3803  * @param   fFlags      Detach flags.
    3804  */
    3805 static DECLCALLBACK(void) drvAudioDetach(PPDMDRVINS pDrvIns, uint32_t fFlags)
    3806 {
    3807     RT_NOREF(fFlags);
    3808 
    3809     PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    3810     PDRVAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIO);
    3811 
    3812     int rc2 = RTCritSectEnter(&pThis->CritSect);
    3813     AssertRC(rc2);
    3814 
    3815     pThis->pHostDrvAudio = NULL;
    3816 
    3817     LogFunc(("%s\n", pThis->szName));
    3818 
    3819     rc2 = RTCritSectLeave(&pThis->CritSect);
    3820     AssertRC(rc2);
    38213838}
    38223839
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