summaryrefslogtreecommitdiffstats
path: root/src/engine/effects
diff options
context:
space:
mode:
authorbe_ <be.0@gmx.com>2018-01-04 17:48:12 -0600
committerbe_ <be.0@gmx.com>2018-01-04 18:08:23 -0600
commit0e728c095c576d79ef4d605c2b98cc87ad89b253 (patch)
treec6657074db9b3519654dba24aaab6bbe4dcd4af5 /src/engine/effects
parent52f54d4f470f96a9f637788eb66322757d042210 (diff)
fix crash enabling PFL after an EffectState is deleted
Diffstat (limited to 'src/engine/effects')
-rw-r--r--src/engine/effects/engineeffect.cpp15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/engine/effects/engineeffect.cpp b/src/engine/effects/engineeffect.cpp
index 5475a0b13b..7df1ef01ba 100644
--- a/src/engine/effects/engineeffect.cpp
+++ b/src/engine/effects/engineeffect.cpp
@@ -71,6 +71,21 @@ void EngineEffect::loadStatesForInputChannel(const ChannelHandle* inputChannel,
// Called from the main thread for garbage collection after an input channel is disabled
void EngineEffect::deleteStatesForInputChannel(const ChannelHandle* inputChannel) {
+ // If an output channel is not presently being processed, for example when
+ // PFL is not active, then EngineEffect::process cannot be relied upon to
+ // set the EffectEnableState from Disabling to Disabled. This must be done
+ // before the next time EngineEffect::process is called for that output
+ // channel, otherwise the EffectEnableState will still be in the intermediate
+ // Disabling state and EffectProcessorImpl::processChannel will try to run
+ // with an EffectState that has already been deleted and cause a crash.
+ // Refer to https://bugs.launchpad.net/mixxx/+bug/1741213
+ // NOTE: ChannelHandleMap is like a map in that it associates an object with
+ // a ChannelHandle key, but it actually backed by a QVarLengthArray, not a
+ // QMap. So it is okay that m_effectEnableStateForChannelMatrix may be
+ // accessed concurrently in the audio engine thread in EngineEffect::process.
+ for (EffectEnableState& effectState : m_effectEnableStateForChannelMatrix[*inputChannel]) {
+ effectState = EffectEnableState::Disabled;
+ }
m_pProcessor->deleteStatesForInputChannel(inputChannel);
}