From 5e77d6b5479ef92caeb0dd93ae070d60b50c73b9 Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Mon, 30 Jun 2008 16:52:10 +0000 Subject: [PATCH] properly terminate worker-threads at mixer-destruction git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1230 0778d3d1-df1d-0410-868b-ea421aaaa00d --- src/core/mixer.cpp | 69 +++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/src/core/mixer.cpp b/src/core/mixer.cpp index ff53dfcb6..fafde2801 100644 --- a/src/core/mixer.cpp +++ b/src/core/mixer.cpp @@ -171,6 +171,10 @@ public: m_jobQueue = _q; } + virtual void quit( void ) + { + m_quit = TRUE; + } private: virtual void run( void ) @@ -178,7 +182,7 @@ private: sampleFrame * working_buf = (sampleFrame *) aligned_malloc( m_mixer->framesPerPeriod() * sizeof( sampleFrame ) ); - while( 1 ) + while( m_quit == FALSE ) { m_queueReadySem->acquire(); for( jobQueueItems::iterator it = @@ -231,6 +235,7 @@ private: aligned_free( working_buf ); } + volatile bool m_quit; mixer * m_mixer; QSemaphore * m_queueReadySem; QSemaphore * m_workersDoneSem; @@ -240,6 +245,31 @@ private: +#define FILL_JOB_QUEUE(_jq,_vec_type,_vec,_job_type,_condition) \ + for( _vec_type::iterator it = _vec.begin(); \ + it != _vec.end(); ++it ) \ + { \ + if( _condition ) \ + { \ + _jq.items.push_back( \ + mixerWorkerThread::jobQueueItem( _job_type, \ + (void *)*it ) );\ + } \ + } + +#define DISTRIBUTE_JOB_QUEUE(_jq) \ + for( int i = 0; i < m_numWorkers; ++i ) \ + { \ + m_workers[i]->setJobQueue( &_jq ); \ + } \ + m_queueReadySem.release( m_numWorkers ); \ + +#define WAIT_FOR_JOBS() \ + m_workersDoneSem.acquire( m_numWorkers ); + + + + mixer::mixer( void ) : m_framesPerPeriod( DEFAULT_BUFFER_SIZE ), m_workingBuf( NULL ), @@ -315,6 +345,19 @@ mixer::mixer( void ) : mixer::~mixer() { + if( m_multiThreaded ) + { + // distribute an empty job-queue so that worker-threads + // get out of their processing-loop + mixerWorkerThread::jobQueue jq; + for( int w = 0; w < m_numWorkers; ++w ) + { + m_workers[w]->quit(); + DISTRIBUTE_JOB_QUEUE(jq); + m_workers[w]->wait(); + } + } + while( m_fifo->available() ) { delete[] m_fifo->read(); @@ -422,30 +465,6 @@ bool mixer::criticalXRuns( void ) const -#define FILL_JOB_QUEUE(_jq,_vec_type,_vec,_job_type,_condition) \ - for( _vec_type::iterator it = _vec.begin(); \ - it != _vec.end(); ++it ) \ - { \ - if( _condition ) \ - { \ - _jq.items.push_back( \ - mixerWorkerThread::jobQueueItem( _job_type, \ - (void *)*it ) );\ - } \ - } - -#define DISTRIBUTE_JOB_QUEUE(_jq) \ - for( int i = 0; i < m_numWorkers; ++i ) \ - { \ - m_workers[i]->setJobQueue( &_jq ); \ - } \ - m_queueReadySem.release( m_numWorkers ); \ - -#define WAIT_FOR_JOBS() \ - m_workersDoneSem.acquire( m_numWorkers ); - - - const surroundSampleFrame * mixer::renderNextBuffer( void ) { microTimer timer;