Skip to content

Commit

Permalink
Don't lock the device state when preparing a new effect state
Browse files Browse the repository at this point in the history
There is technically a small race condition with the device getting reset on a
separate thread at the same time, but the way the locks get ordered would
otherwise risk a deadlock (alAuxiliaryEffectSloti first locks the context's
mPropLock and mEffectSlotLock before initEffect locks the device's StateLock,
while alcCreateContext and alcResetDeviceSOFT first locks the device's
StateLock before UpdateDeviceParams locks the context's mPropLock and
mEffectSlotLock).

In contrast, the race condition may (depending on timing) set up the effect
state with an older or mixed device format and assign invalid or null pointers,
which will get properly reset and cleaned up after the device is reconfigured
and before restarting.
  • Loading branch information
kcat committed Jun 4, 2024
1 parent 6d5d9a8 commit fddfbb6
Showing 1 changed file with 0 additions and 4 deletions.
4 changes: 0 additions & 4 deletions al/auxeffectslot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -592,14 +592,12 @@ try {
slot->Buffer = buffer;
bufferlock.unlock();

auto statelock = std::unique_lock{device->StateLock};
state->mOutTarget = device->Dry.Buffer;
{
FPUCtl mixer_mode{};
state->deviceUpdate(device, buffer);
}
slot->Effect.State = std::move(state);
statelock.unlock();

slot->mPropsDirty = false;
slot->updateProps(context);
Expand Down Expand Up @@ -627,7 +625,6 @@ try {
slot->Buffer = buffer;
bufferlock.unlock();

auto statelock = std::unique_lock{device->StateLock};
FPUCtl mixer_mode{};
auto *state = slot->Effect.State.get();
state->deviceUpdate(device, buffer);
Expand Down Expand Up @@ -899,7 +896,6 @@ ALenum ALeffectslot::initEffect(ALuint effectId, ALenum effectType, const Effect
al::intrusive_ptr<EffectState> state{factory->create()};

ALCdevice *device{context->mALDevice.get()};
std::unique_lock<std::mutex> statelock{device->StateLock};
state->mOutTarget = device->Dry.Buffer;
{
FPUCtl mixer_mode{};
Expand Down

0 comments on commit fddfbb6

Please sign in to comment.