Merge pull request #2872 from jasp00/krem

Fix infinite loop in FxMixer and some resource releases
This commit is contained in:
Javier Serrano Polo
2016-06-27 00:54:23 +00:00
committed by GitHub
8 changed files with 55 additions and 36 deletions

View File

@@ -201,7 +201,6 @@ private:
// make sure we have at least num channels
void allocateChannelsTo(int num);
QMutex m_sendsMutex;
int m_lastSoloed;

View File

@@ -30,8 +30,6 @@
#include <QStackedLayout>
#include <QScrollArea>
#include "FxLine.h"
#include "FxMixer.h"
#include "ModelView.h"
#include "Engine.h"
#include "Fader.h"

View File

@@ -211,9 +211,11 @@ FxMixer::~FxMixer()
{
deleteChannelSend( m_fxRoutes.first() );
}
for( int i = 0; i < m_fxChannels.size(); ++i )
while( m_fxChannels.size() )
{
delete m_fxChannels[i];
FxChannel * f = m_fxChannels[m_fxChannels.size() - 1];
m_fxChannels.pop_back();
delete f;
}
}
@@ -288,8 +290,6 @@ void FxMixer::deleteChannel( int index )
// channel deletion is performed between mixer rounds
Engine::mixer()->requestChangeInModel();
FxChannel * ch = m_fxChannels[index];
// go through every instrument and adjust for the channel index change
TrackContainer::TrackList tracks;
tracks += Engine::getSong()->tracks();
@@ -315,6 +315,8 @@ void FxMixer::deleteChannel( int index )
}
}
FxChannel * ch = m_fxChannels[index];
// delete all of this channel's sends and receives
while( ! ch->m_sends.isEmpty() )
{
@@ -326,8 +328,8 @@ void FxMixer::deleteChannel( int index )
}
// actually delete the channel
delete m_fxChannels[index];
m_fxChannels.remove(index);
delete ch;
for( int i = index; i < m_fxChannels.size(); ++i )
{
@@ -434,7 +436,7 @@ FxRoute * FxMixer::createRoute( FxChannel * from, FxChannel * to, float amount )
{
return NULL;
}
m_sendsMutex.lock();
Engine::mixer()->requestChangeInModel();
FxRoute * route = new FxRoute( from, to, amount );
// add us to from's sends
@@ -445,7 +447,7 @@ FxRoute * FxMixer::createRoute( FxChannel * from, FxChannel * to, float amount )
// add us to fxmixer's list
Engine::fxMixer()->m_fxRoutes.append( route );
m_sendsMutex.unlock();
Engine::mixer()->doneChangeInModel();
return route;
}
@@ -472,7 +474,7 @@ void FxMixer::deleteChannelSend( fx_ch_t fromChannel, fx_ch_t toChannel )
void FxMixer::deleteChannelSend( FxRoute * route )
{
m_sendsMutex.lock();
Engine::mixer()->requestChangeInModel();
// remove us from from's sends
route->sender()->m_sends.remove( route->sender()->m_sends.indexOf( route ) );
// remove us from to's receives
@@ -480,7 +482,7 @@ void FxMixer::deleteChannelSend( FxRoute * route )
// remove us from fxmixer's list
Engine::fxMixer()->m_fxRoutes.remove( Engine::fxMixer()->m_fxRoutes.indexOf( route ) );
delete route;
m_sendsMutex.unlock();
Engine::mixer()->doneChangeInModel();
}
@@ -571,33 +573,46 @@ void FxMixer::masterMix( sampleFrame * _buf )
{
const int fpp = Engine::mixer()->framesPerPeriod();
if( m_sendsMutex.tryLock() )
// add the channels that have no dependencies (no incoming senders, ie.
// no receives) to the jobqueue. The channels that have receives get
// added when their senders get processed, which is detected by
// dependency counting.
// also instantly add all muted channels as they don't need to care
// about their senders, and can just increment the deps of their
// recipients right away.
MixerWorkerThread::resetJobQueue( MixerWorkerThread::JobQueue::Dynamic );
for( FxChannel * ch : m_fxChannels )
{
// add the channels that have no dependencies (no incoming senders, ie. no receives)
// to the jobqueue. The channels that have receives get added when their senders get processed, which
// is detected by dependency counting.
// also instantly add all muted channels as they don't need to care about their senders, and can just increment the deps of
// their recipients right away.
MixerWorkerThread::resetJobQueue( MixerWorkerThread::JobQueue::Dynamic );
ch->m_muted = ch->m_muteModel.value();
if( ch->m_muted ) // instantly "process" muted channels
{
ch->processed();
ch->done();
}
else if( ch->m_receives.size() == 0 )
{
ch->m_queued = true;
MixerWorkerThread::addJob( ch );
}
}
while( m_fxChannels[0]->state() != ThreadableJob::Done )
{
bool found = false;
for( FxChannel * ch : m_fxChannels )
{
ch->m_muted = ch->m_muteModel.value();
if( ch->m_muted ) // instantly "process" muted channels
int s = ch->state();
if( s == ThreadableJob::Queued
|| s == ThreadableJob::InProgress )
{
ch->processed();
ch->done();
}
else if( ch->m_receives.size() == 0 )
{
ch->m_queued = true;
MixerWorkerThread::addJob( ch );
found = true;
break;
}
}
while( m_fxChannels[0]->state() != ThreadableJob::Done )
if( !found )
{
MixerWorkerThread::startAndWaitForJobs();
break;
}
m_sendsMutex.unlock();
MixerWorkerThread::startAndWaitForJobs();
}
// handle sample-exact data in master volume fader

View File

@@ -135,6 +135,7 @@ void JournallingObject::changeID( jo_id_t _id )
return;
}
Engine::projectJournal()->freeID( m_id );
Engine::projectJournal()->reallocID( _id, this );
m_id = _id;
}

View File

@@ -25,6 +25,7 @@
#include "Song.h"
#include <QTextStream>
#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QFileInfo>
#include <QMessageBox>

View File

@@ -341,7 +341,10 @@ void MidiPort::updateMidiPortMode()
emit writablePortsChanged();
emit modeChanged();
Engine::getSong()->setModified();
if( Engine::getSong() )
{
Engine::getSong()->setModified();
}
}

View File

@@ -41,6 +41,8 @@
#include "Knob.h"
#include "Engine.h"
#include "embed.h"
#include "FxLine.h"
#include "FxMixer.h"
#include "GuiApplication.h"
#include "MainWindow.h"
#include "Mixer.h"

View File

@@ -84,12 +84,12 @@ EffectRackView::~EffectRackView()
void EffectRackView::clearViews()
{
for( QVector<EffectView *>::Iterator it = m_effectViews.begin();
it != m_effectViews.end(); ++it )
while( m_effectViews.size() )
{
delete *it;
EffectView * e = m_effectViews[m_effectViews.size() - 1];
m_effectViews.pop_back();
delete e;
}
m_effectViews.clear();
}