Fix crash when opening/closing mixer very quickly during playback #14790
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Resolves: #13903
Resolves: #9467
What happened:
AudioSignalsNotifier::updateSignalValues(…)
, we callaudioSignalChanges.send(audioChNumber, signalVal);
.QInvoker
inAbstractInvoker::invoke(int type, const NotifyData& data)
. Also, a call to thisQInvoker
'sinvoke()
method, followed by the deletion of thisQInvoker
is queued toQueuedInvoker
.QInvoker
, it adds itself to theAbstractInvoker
's list ofm_qInvokers
by callingAbstractInvoker::addQInvoker(…)
.AbstractInvoker::removeCallBack(…)
is called, which "invalidates" theQInvoker
; that means: theQInvoker
's pointer to theAbstractInvoker
is set tonullptr
.QInvoker
'sinvoke()
method is still called (because that had been queued already, see point 2). This doesn't do much :)QInvoker
is deleted, because that was also queued.QInvoker
from theAbstractInvoker
's list ofm_qInvokers
by callingAbstractInvoker::removeQInvoker(…)
. But in this case, theQInvoker
was already invalidated, so it has no reference to theAbstractInvoker
anymore, so it doesn't remove itself from the list ofm_qInvokers
. So that list now contains a pointer to deleted memory!AbstractInvoker::removeCallBack(…)
is called again, for some callback (which one exactly isn't relevant).m_qInvokers
, and reads a bit of all of them, to look whether they belong to the callback that is being removed (and thus need to be invalidated).QInvoker
that was still in the list! 💥