summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/Audio/DevHdaStream.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 22:55:52 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 22:55:52 +0000
commitcd47c2446f1a9dee96610f298989848f8986a8be (patch)
tree02c30d62a9164987d0aaba2f72c58a50053205d6 /src/VBox/Devices/Audio/DevHdaStream.cpp
parentReleasing progress-linux version 7.0.14-dfsg-4~progress7.99u1. (diff)
downloadvirtualbox-cd47c2446f1a9dee96610f298989848f8986a8be.tar.xz
virtualbox-cd47c2446f1a9dee96610f298989848f8986a8be.zip
Merging upstream version 7.0.16-dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/Audio/DevHdaStream.cpp')
-rw-r--r--src/VBox/Devices/Audio/DevHdaStream.cpp60
1 files changed, 36 insertions, 24 deletions
diff --git a/src/VBox/Devices/Audio/DevHdaStream.cpp b/src/VBox/Devices/Audio/DevHdaStream.cpp
index aa6b0535..9bb27a4a 100644
--- a/src/VBox/Devices/Audio/DevHdaStream.cpp
+++ b/src/VBox/Devices/Audio/DevHdaStream.cpp
@@ -797,18 +797,6 @@ int hdaR3StreamSetUp(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShar
* Set up internal ring buffer.
*/
- /* (Re-)Allocate the stream's internal DMA buffer,
- * based on the timing *and* PCM properties we just got above. */
- if (pStreamR3->State.pCircBuf)
- {
- RTCircBufDestroy(pStreamR3->State.pCircBuf);
- pStreamR3->State.pCircBuf = NULL;
- pStreamR3->State.StatDmaBufSize = 0;
- pStreamR3->State.StatDmaBufUsed = 0;
- }
- pStreamShared->State.offWrite = 0;
- pStreamShared->State.offRead = 0;
-
/*
* The default internal ring buffer size must be:
*
@@ -857,16 +845,37 @@ int hdaR3StreamSetUp(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShar
rc = VERR_INVALID_PARAMETER);
if (RT_SUCCESS(rc))
{
- rc = RTCircBufCreate(&pStreamR3->State.pCircBuf, cbCircBuf);
- if (RT_SUCCESS(rc))
+ /**
+ * Note: Only re-create the DMA buffer if the size actually has changed.
+ *
+ * Otherwise do *not* reset the stream's circular buffer here, as the audio mixer still relies on
+ * previously announced DMA data (via AudioMixerSinkDrainAndStop()) and processes it asynchronously.
+ * Resetting the buffer here will cause a race condition. See @bugref{10354}. */
+ if (pStreamR3->State.StatDmaBufSize != cbCircBuf)
{
- pStreamR3->State.StatDmaBufSize = cbCircBuf;
+ /* (Re-)Allocate the stream's internal DMA buffer,
+ * based on the timing *and* PCM properties we just got above. */
+ if (pStreamR3->State.pCircBuf)
+ {
+ RTCircBufDestroy(pStreamR3->State.pCircBuf);
+ pStreamR3->State.pCircBuf = NULL;
+ pStreamR3->State.StatDmaBufSize = 0;
+ pStreamR3->State.StatDmaBufUsed = 0;
+ }
+ pStreamShared->State.offWrite = 0;
+ pStreamShared->State.offRead = 0;
- /*
- * Forward the timer frequency hint to TM as well for better accuracy on
- * systems w/o preemption timers (also good for 'info timers').
- */
- PDMDevHlpTimerSetFrequencyHint(pDevIns, pStreamShared->hTimer, uTransferHz);
+ rc = RTCircBufCreate(&pStreamR3->State.pCircBuf, cbCircBuf);
+ if (RT_SUCCESS(rc))
+ {
+ pStreamR3->State.StatDmaBufSize = cbCircBuf;
+
+ /*
+ * Forward the timer frequency hint to TM as well for better accuracy on
+ * systems w/o preemption timers (also good for 'info timers').
+ */
+ PDMDevHlpTimerSetFrequencyHint(pDevIns, pStreamShared->hTimer, uTransferHz);
+ }
}
}
@@ -1003,10 +1012,9 @@ void hdaR3StreamReset(PHDASTATE pThis, PHDASTATER3 pThisCC, PHDASTREAM pStreamSh
pStreamShared->State.idxScheduleLoop = 0;
pStreamShared->State.fInputPreBuffered = false;
- if (pStreamR3->State.pCircBuf)
- RTCircBufReset(pStreamR3->State.pCircBuf);
- pStreamShared->State.offWrite = 0;
- pStreamShared->State.offRead = 0;
+ /* Note: Do *not* reset the stream's circular buffer here, as the audio mixer still relies on
+ * previously announced DMA data (via AudioMixerSinkDrainAndStop()) and processes it asynchronously.
+ * Resetting the buffer here will cause a race condition. See @bugref{10354}. */
/* Report that we're done resetting this stream. */
HDA_STREAM_REG(pThis, CTL, uSD) = 0;
@@ -1041,6 +1049,8 @@ int hdaR3StreamEnable(PHDASTATE pThis, PHDASTREAM pStreamShared, PHDASTREAMR3 pS
PAUDMIXSINK const pSink = pStreamR3->pMixSink ? pStreamR3->pMixSink->pMixSink : NULL;
if (pSink)
{
+ AudioMixerSinkLock(pSink);
+
if (fEnable)
{
if (pStreamR3->State.pAioRegSink != pSink)
@@ -1060,6 +1070,8 @@ int hdaR3StreamEnable(PHDASTATE pThis, PHDASTREAM pStreamShared, PHDASTREAMR3 pS
else
rc = AudioMixerSinkDrainAndStop(pSink,
pStreamR3->State.pCircBuf ? (uint32_t)RTCircBufUsed(pStreamR3->State.pCircBuf) : 0);
+
+ AudioMixerSinkUnlock(pSink);
}
if ( RT_SUCCESS(rc)
&& fEnable