fix: fix audio Mixer freeze
This commit is contained in:
@@ -383,17 +383,36 @@ namespace Drivers::Audio::Mixer {
|
||||
g_lock.Acquire();
|
||||
VirtualStream& s = g_streams[handle];
|
||||
bool changed = false;
|
||||
// Pull the ring pointer out of the slot before freeing it. Once
|
||||
// s.active=false and s.ring=nullptr are visible under the lock no
|
||||
// other path can reach this pointer, so the actual PFA free can run
|
||||
// with the lock released — keeping the HDA buffer-complete IRQ from
|
||||
// spinning on g_lock while ReallocConsecutive walks the free list.
|
||||
int16_t* ringToFree = nullptr;
|
||||
bool lastStream = false;
|
||||
if (s.active) {
|
||||
FreeRing(s.ring);
|
||||
ringToFree = s.ring;
|
||||
s.ring = nullptr;
|
||||
s.active = false;
|
||||
s.ownerPid = 0;
|
||||
s.name[0] = '\0';
|
||||
if (g_activeCount > 0) g_activeCount--;
|
||||
lastStream = (g_activeCount == 0);
|
||||
BumpSerialLocked();
|
||||
changed = true;
|
||||
}
|
||||
// Quiesce the hardware when the final virtual stream goes away so
|
||||
// the HDA DMA ring stops looping its last 32 KiB of samples. The
|
||||
// next Open() reopens the HDA stream via EnsureHdaOpen().
|
||||
bool closeHda = lastStream && g_hdaOpened;
|
||||
int hdaHandle = g_hdaHandle;
|
||||
if (closeHda) {
|
||||
g_hdaOpened = false;
|
||||
g_hdaHandle = -1;
|
||||
}
|
||||
g_lock.Release();
|
||||
if (closeHda) IntelHda::Close(hdaHandle);
|
||||
if (ringToFree) FreeRing(ringToFree);
|
||||
if (changed) Sched::WakeObjectWaiters((void*)&g_serial);
|
||||
}
|
||||
|
||||
@@ -495,12 +514,14 @@ namespace Drivers::Audio::Mixer {
|
||||
}
|
||||
|
||||
void CleanupProcess(int pid) {
|
||||
int16_t* ringsToFree[MAX_STREAMS] = {};
|
||||
int ringCount = 0;
|
||||
g_lock.Acquire();
|
||||
bool changed = false;
|
||||
for (int i = 0; i < MAX_STREAMS; i++) {
|
||||
VirtualStream& s = g_streams[i];
|
||||
if (s.active && s.ownerPid == pid) {
|
||||
FreeRing(s.ring);
|
||||
ringsToFree[ringCount++] = s.ring;
|
||||
s.ring = nullptr;
|
||||
s.active = false;
|
||||
s.ownerPid = 0;
|
||||
@@ -509,8 +530,16 @@ namespace Drivers::Audio::Mixer {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
bool closeHda = changed && (g_activeCount == 0) && g_hdaOpened;
|
||||
int hdaHandle = g_hdaHandle;
|
||||
if (closeHda) {
|
||||
g_hdaOpened = false;
|
||||
g_hdaHandle = -1;
|
||||
}
|
||||
if (changed) BumpSerialLocked();
|
||||
g_lock.Release();
|
||||
if (closeHda) IntelHda::Close(hdaHandle);
|
||||
for (int i = 0; i < ringCount; i++) FreeRing(ringsToFree[i]);
|
||||
if (changed) Sched::WakeObjectWaiters((void*)&g_serial);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user