VirtualBox

Changeset 108536 in vbox


Ignore:
Timestamp:
Mar 12, 2025 7:34:43 PM (2 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
167928
Message:

Audio/DrvHostAudioWasApi: Follow-up fix for r167721 -- check the passed-in device interface before trying to look it up in the cache. Remove stale / non-functioning device interfaces from the cache and try re-creating it. Logging tweaks to hopefully better find the cause and recovery gaps. bugref:10844

File:
1 edited

Legend:

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

    r108508 r108536  
    11531153 * If lookup fails, a new entry will be created.
    11541154 *
    1155  * @note    Called holding the cache's lock, returning without holding it!
     1155 * @note    Called holding the cache's lock (if \a fUseCache is @true), returning without holding it!
    11561156 */
    11571157static int drvHostAudioWasCacheLookupOrCreateConfig(PDRVHOSTAUDIOWAS pThis, PDRVHOSTAUDIOWASCACHEDEV pDevEntry,
    1158                                                     PCPDMAUDIOSTREAMCFG pCfgReq, bool fOnWorker,
     1158                                                    PCPDMAUDIOSTREAMCFG pCfgReq, bool fUseCache, bool fOnWorker,
    11591159                                                    PDRVHOSTAUDIOWASCACHEDEVCFG *ppDevCfg)
    11601160{
     
    11641164     * Check if we've got a matching config.
    11651165     */
    1166     if (pThis->fCacheEnabled)
     1166    if (fUseCache)
    11671167    {
    11681168        pDevCfg = drvHostAudioWasCacheLookupLocked(pDevEntry, &pCfgReq->Props);
     
    11931193    pDevCfg->nsLastUsed        = pDevCfg->nsCreated;
    11941194
    1195     if (pThis->fCacheEnabled)
     1195    if (fUseCache)
    11961196    {
    11971197        uint32_t cCacheEntries;
     
    12571257    *ppDevCfg = NULL;
    12581258
     1259    LogRel2(("WasAPI: Looking up or creating cache entry (caching is set to %s, iface %p)\n",
     1260             pThis->fCacheEnabled ? "enabled" : "disabled", pIDevice));
     1261
    12591262    /*
    12601263     * Get the device ID so we can perform the lookup.
     
    12671270        bool fLookupOrCreateInCache = pThis->fCacheEnabled; /* Whether to lookup and/or create the device in our cache. */
    12681271
    1269         /* First, try retrieving the current device state here as a yet another meassure for
     1272        /* First, try retrieving the current device state of the passed device here as a yet another meassure for
    12701273         * AUDCLNT_E_DEVICE_INVALIDATED errors. We try not to cache malfunctioning devices here.  See @bugref{10844} */
    12711274        DWORD dwState;
     
    12861289        }
    12871290
    1288         PDRVHOSTAUDIOWASCACHEDEV pDevEntry;
    1289         size_t const             cwcDevId = RTUtf16Len(pwszDevId);
     1291        PDRVHOSTAUDIOWASCACHEDEV pDevEntry = NULL;
     1292        size_t const             cwcDevId  = RTUtf16Len(pwszDevId);
    12901293
    12911294        if (fLookupOrCreateInCache)
     
    12931296            LogRel2(("WasAPI: Checking for cached device '%ls' ...\n", pwszDevId));
    12941297
     1298#define DEVICE_STALE_OR_INVALID_BREAK(a_LogRel2What) \
     1299    { \
     1300        LogRel2(a_LogRel2What); \
     1301        LogRel(("WasAPI: Stale or invalid audio interface '%ls' detected!\n", pDevEntry->wszDevId)); \
     1302        rc = VERR_AUDIO_STREAM_NOT_READY; \
     1303        break; \
     1304    }
    12951305            /*
    12961306             * The cache has two levels, so first the device entry.
     
    13051315                {
    13061316                    /*
    1307                      * Cache hit -- here we now need to also check if the device interface we want to look up
     1317                     * Cache hit.
     1318                     * First we need to check if the cached device interface is in a working (active) shape.
     1319                     */
     1320                    AssertPtrBreakStmt(pDevEntry->pIDevice, rc = VERR_AUDIO_STREAM_NOT_READY); /* Paranoia. */
     1321                    hrc = pDevEntry->pIDevice->GetState(&dwState);
     1322                    if (SUCCEEDED(hrc))
     1323                    {
     1324                        if (dwState != DEVICE_STATE_ACTIVE)
     1325                            DEVICE_STALE_OR_INVALID_BREAK(("WasAPI: Cache hit for device '%ls': Is in non-active state (state is %s)\n",
     1326                                                           pDevEntry->wszDevId, drvHostAudioWasMMDeviceStateToString(dwState)));
     1327                    }
     1328                    else
     1329                        DEVICE_STALE_OR_INVALID_BREAK(("WasAPI: Cache hit for device '%ls': Unable to retrieve state (hr=%#x)\n",
     1330                                                       pDevEntry->wszDevId, hrc));
     1331                    /*
     1332                     * Next we now need to also check if the device interface we want to look up
    13081333                     * actually matches the one we have in the cache entry.
    13091334                     *
     
    13141339                     */
    13151340                    if (pDevEntry->pIDevice != pIDevice)
    1316                         LogRel2(("WasAPI: Cache hit for device '%ls': Stale interface (new: %p, old: %p)\n",
    1317                                  pDevEntry->wszDevId, pIDevice, pDevEntry->pIDevice));
     1341                        DEVICE_STALE_OR_INVALID_BREAK(("WasAPI: Cache hit for device '%ls': Stale interface detected (new: %p, old: %p)\n",
     1342                                                       pDevEntry->wszDevId, pIDevice, pDevEntry->pIDevice));
    13181343
    13191344                    LogRel2(("WasAPI: Cache hit for device '%ls' (iface %p)\n", pwszDevId, pIDevice));
     
    13221347                    pwszDevId = NULL;
    13231348
    1324                     return drvHostAudioWasCacheLookupOrCreateConfig(pThis, pDevEntry, pCfgReq, fOnWorker, ppDevCfg);
     1349                    return drvHostAudioWasCacheLookupOrCreateConfig(pThis, pDevEntry, pCfgReq,
     1350                                                                    true /* fUseCache */, fOnWorker, ppDevCfg);
    13251351                }
    13261352            }
    13271353            RTCritSectLeave(&pThis->CritSectCache);
    13281354
    1329             LogRel2(("WasAPI: Cache miss for device '%ls' (iface %p)\n", pwszDevId, pIDevice));
    1330 
    1331 #undef LOG_STALE_DEVICE_BREAK
    1332 #undef LOG_STALE_DEVICE
    1333 
    1334         }
    1335         else
    1336             LogRel2(("WasAPI: Not caching device '%ls' (iface %p)\n", pwszDevId, pIDevice));
     1355            if (!pDevEntry)
     1356                LogRel2(("WasAPI: Cache miss for device '%ls' (iface %p)\n", pwszDevId, pIDevice));
     1357
     1358#undef DEVICE_STALE_OR_INVALID_BREAK
     1359        }
    13371360
    13381361        /*
    1339          * Device not in the cache, add it.
     1362         * If we got a stale or somehow other invalid cache entry, remove it first.
     1363         */
     1364        if (   pThis->fCacheEnabled
     1365            && pDevEntry /* Cache hit? */
     1366            && rc == VERR_AUDIO_STREAM_NOT_READY)
     1367        {
     1368            LogRel2(("WasAPI: Removing stale device '%ls' from cache (iface %p)\n", pDevEntry->wszDevId, pDevEntry->pIDevice));
     1369
     1370            RTCritSectEnter(&pThis->CritSectCache);
     1371            RTListNodeRemove(&pDevEntry->ListEntry);
     1372            RTCritSectLeave(&pThis->CritSectCache);
     1373
     1374            drvHostAudioWasCacheDestroyDevEntry(pThis, pDevEntry);
     1375            pDevEntry = NULL;
     1376
     1377            rc = VINF_SUCCESS;
     1378        }
     1379
     1380        /*
     1381         * Device not in the cache (anymore), (re-)add it.
    13401382         */
    13411383        pDevEntry = (PDRVHOSTAUDIOWASCACHEDEV)RTMemAllocZVar(RT_UOFFSETOF_DYN(DRVHOSTAUDIOWASCACHEDEV, wszDevId[cwcDevId + 1]));
     
    13601402            if (fLookupOrCreateInCache)
    13611403            {
     1404                /* Make sure to enter the cache's critsect again for the following calls. */
     1405                RTCritSectEnter(&pThis->CritSectCache);
     1406
    13621407                /*
    13631408                 * Before adding the device to the cache, check that someone didn't race us adding it.
    13641409                 */
    1365                 RTCritSectEnter(&pThis->CritSectCache);
    13661410                PDRVHOSTAUDIOWASCACHEDEV pDevEntry2;
    13671411                RTListForEach(&pThis->CacheHead, pDevEntry2, DRVHOSTAUDIOWASCACHEDEV, ListEntry)
     
    13791423
    13801424                        LogRel2(("WasAPI: Lost race adding device '%ls' (node %p)\n", pDevEntry2->wszDevId, pDevEntry2));
    1381                         return drvHostAudioWasCacheLookupOrCreateConfig(pThis, pDevEntry2, pCfgReq, fOnWorker, ppDevCfg);
     1425                        return drvHostAudioWasCacheLookupOrCreateConfig(pThis, pDevEntry2, pCfgReq,
     1426                                                                        true /* fUseCache */, fOnWorker, ppDevCfg);
    13821427                    }
    13831428                }
     
    13861431                LogRel2(("WasAPI: Added device '%ls' to cache (node %p)\n", pDevEntry->wszDevId, pDevEntry));
    13871432            }
    1388 
    1389             return drvHostAudioWasCacheLookupOrCreateConfig(pThis, pDevEntry, pCfgReq, fOnWorker, ppDevCfg);
     1433            else
     1434                LogRel2(("WasAPI: Not caching device '%ls' (iface %p)\n", pDevEntry->wszDevId, pIDevice));
     1435
     1436            return drvHostAudioWasCacheLookupOrCreateConfig(pThis, pDevEntry, pCfgReq,
     1437                                                            fLookupOrCreateInCache /* fUseCache */, fOnWorker, ppDevCfg);
    13901438        }
    13911439        CoTaskMemFree(pwszDevId);
     
    16811729                            rc = RTUtf16ToUtf8Ex(pDev->wszDevId, RTSTR_MAX, &pDev->Core.pszId, cbId, NULL);
    16821730                            if (RT_SUCCESS(rc))
     1731                            {
    16831732                                PDMAudioHostEnumAppend(pDevEnm, &pDev->Core);
     1733                                LogRel2(("WasAPI: Device '%ls': %p\n", pDev->wszDevId, pIDevice));
     1734                           }
    16841735                            else
    16851736                                PDMAudioHostDevFree(&pDev->Core);
     
    26572708                cbPending = PDMAudioPropsFramesToBytes(&pStreamWas->Cfg.Props, RT_MIN(cFramesPending, VBOX_WASAPI_MAX_PADDING));
    26582709            }
    2659             else
    2660                 LogRelMax(64, ("WasAPI: GetCurrentPadding failed on '%s': %Rhrc\n", pStreamWas->Cfg.szName, hrc));
     2710            else /* Don't use LogRelMax here to get a more accurate tracking about when this works again wrt recovery. */
     2711                LogRel2(("WasAPI: GetCurrentPadding[R] failed on '%s': %Rhrc\n", pStreamWas->Cfg.szName, hrc));
    26612712        }
    26622713    }
     
    27012752            }
    27022753        }
    2703         else
    2704             LogRelMax(64, ("WasAPI: GetCurrentPadding failed on '%s': %Rhrc\n", pStreamWas->Cfg.szName, hrc));
     2754        else /* Don't use LogRelMax here to get a more accurate tracking about when this works again wrt recovery. */
     2755            LogRel2(("WasAPI: GetCurrentPadding[W] failed on '%s': %Rhrc\n", pStreamWas->Cfg.szName, hrc));
    27052756    }
    27062757
Note: See TracChangeset for help on using the changeset viewer.

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