From 9d1867c7ebf729d4ad59efef249876a4e0c39dff Mon Sep 17 00:00:00 2001 From: Fastigium Date: Tue, 16 Feb 2016 13:34:13 +0100 Subject: [PATCH] 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. --- src/core/Mixer.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/core/Mixer.cpp b/src/core/Mixer.cpp index 92124a660..012144a2c 100644 --- a/src/core/Mixer.cpp +++ b/src/core/Mixer.cpp @@ -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 );