Make Mixer::removePlayHandle check m_newPlayHandles, too

This fixes a problem where a PresetPreviewPlayHandle would be put in
m_newPlayHandles to be added, then "removed" before it was actually added,
leaving it dangling.
This commit is contained in:
Fastigium
2016-02-16 13:34:13 +01:00
committed by Jesse Feddema
parent ca7c90a99c
commit 9d1867c7eb

View File

@@ -642,12 +642,32 @@ void Mixer::removePlayHandle( PlayHandle * _ph )
{
lockPlayHandleRemoval();
_ph->audioPort()->removePlayHandle( _ph );
bool removedFromList = false;
// Check m_newPlayHandles first because doing it the other way around
// creates a race condition
m_playHandleMutex.lock();
PlayHandleList::Iterator it =
qFind( m_playHandles.begin(),
m_playHandles.end(), _ph );
qFind( m_newPlayHandles.begin(),
m_newPlayHandles.end(), _ph );
if( it != m_newPlayHandles.end() )
{
m_newPlayHandles.erase( it );
removedFromList = true;
}
m_playHandleMutex.unlock();
// Now check m_playHandles
it = qFind( m_playHandles.begin(),
m_playHandles.end(), _ph );
if( it != m_playHandles.end() )
{
m_playHandles.erase( it );
removedFromList = true;
}
// Only deleting PlayHandles that were actually found in the list
// "fixes crash when previewing a preset under high load"
// (See tobydox's 2008 commit 4583e48)
if ( removedFromList )
{
if( _ph->type() == PlayHandle::TypeNotePlayHandle )
{
NotePlayHandleManager::release( (NotePlayHandle*) _ph );