zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

commit 0db90fe9cc37b99c7e63f894b7787b72bfde217e
parent 40bbd551ea7becd6c3f55ad0ea501323f281c26a
Author: fundamental <[email protected]>
Date:   Wed, 16 Dec 2009 17:36:53 -0500

Nio: Cleaning up system, so a safe shutdown works

Diffstat:
Msrc/Nio/AlsaEngine.cpp | 12++++++++++++
Msrc/Nio/AlsaEngine.h | 4++--
Msrc/Nio/AudioOut.cpp | 5+++++
Msrc/Nio/AudioOut.h | 3++-
Msrc/Nio/OssEngine.cpp | 3++-
Msrc/Nio/OutMgr.cpp | 53++++++++++++++++++++++++++++++++++-------------------
Msrc/Nio/OutMgr.h | 2+-
Msrc/main.cpp | 1+
8 files changed, 59 insertions(+), 24 deletions(-)

diff --git a/src/Nio/AlsaEngine.cpp b/src/Nio/AlsaEngine.cpp @@ -42,9 +42,19 @@ AlsaEngine::AlsaEngine(OutMgr *out) // midi.alsaId = -1; // midi.pThread = 0; + pthread_mutex_init(&close_m, NULL); threadStop = true; } +AlsaEngine::~AlsaEngine() +{ + Stop(); + pthread_mutex_lock(&close_m); + pthread_mutex_unlock(&close_m); + pthread_mutex_destroy(&close_m); +} + + //bool AlsaEngine::openMidi() //{ // midi.device = config.cfg.midiDevice; @@ -414,6 +424,7 @@ void AlsaEngine::OpenStuff() void AlsaEngine::RunStuff() { + pthread_mutex_lock(&close_m); while (!threadStop()) { buffer = interleave(getNext()); rc = snd_pcm_writei(handle, buffer, SOUND_BUFFER_SIZE); @@ -428,4 +439,5 @@ void AlsaEngine::RunStuff() //else if (rc != (int)frames) // cerr << "short write, write " << rc << "frames" << endl; } + pthread_mutex_unlock(&close_m); } diff --git a/src/Nio/AlsaEngine.h b/src/Nio/AlsaEngine.h @@ -35,7 +35,7 @@ class AlsaEngine : public AudioOut//, MidiIn { public: AlsaEngine(OutMgr *out); - ~AlsaEngine() { }; + ~AlsaEngine(); //bool openMidi(); bool Start(); @@ -103,7 +103,7 @@ class AlsaEngine : public AudioOut//, MidiIn void RunStuff(); void OpenStuff(); - + pthread_mutex_t close_m; }; #endif diff --git a/src/Nio/AudioOut.cpp b/src/Nio/AudioOut.cpp @@ -33,6 +33,11 @@ AudioOut::AudioOut(OutMgr *out) pthread_cond_init (&outBuf_cv, NULL); } +AudioOut::~AudioOut() +{ +#warning TODO destroy other mutex +} + void AudioOut::out(const Stereo<Sample> smps) { pthread_mutex_lock(&outBuf_mutex); diff --git a/src/Nio/AudioOut.h b/src/Nio/AudioOut.h @@ -32,7 +32,7 @@ class AudioOut { public: AudioOut(OutMgr *out); - virtual ~AudioOut() {}; + virtual ~AudioOut(); /**Start the Driver*/ virtual bool Start()=0; @@ -59,6 +59,7 @@ class AudioOut pthread_cond_t outBuf_cv; OutMgr *manager; +#warning TODO remove threadStop in favor of enabled //thread resources Atomic<bool> threadStop; pthread_t pThread; diff --git a/src/Nio/OssEngine.cpp b/src/Nio/OssEngine.cpp @@ -51,7 +51,7 @@ OssEngine::OssEngine(OutMgr *out) OssEngine::~OssEngine() { - close(snd_handle); + Stop(); delete [] smps; } @@ -93,6 +93,7 @@ void OssEngine::Stop() { threadStop = true; enabled = false; + close(snd_handle); } void *OssEngine::_AudioThread(void *arg) diff --git a/src/Nio/OutMgr.cpp b/src/Nio/OutMgr.cpp @@ -16,12 +16,12 @@ using namespace std; OutMgr *sysOut; OutMgr::OutMgr(Master *nmaster) - :numRequests(0) + :running(false),numRequests(0) { - running = false; master = nmaster; //initialize mutex + pthread_mutex_init(&close_m, NULL); pthread_mutex_init(&mutex, NULL); pthread_mutex_init(&processing, NULL); pthread_cond_init(&needsProcess, NULL); @@ -51,10 +51,24 @@ OutMgr::OutMgr(Master *nmaster) OutMgr::~OutMgr() { + for(map<string,AudioOut*>::iterator itr = managedOuts.begin(); + itr != managedOuts.end(); ++itr) { + itr->second->Stop(); + } running = false; + pthread_mutex_lock(&processing); + pthread_cond_signal(&needsProcess); + pthread_mutex_unlock(&processing); pthread_mutex_lock(&close_m); - pthread_cond_wait(&close_cond, &close_m); pthread_mutex_unlock(&close_m); + for(map<string,AudioOut*>::iterator itr = managedOuts.begin(); + itr != managedOuts.end(); ++itr) { + delete itr->second; + } + pthread_mutex_destroy(&close_m); + pthread_mutex_destroy(&mutex); + pthread_mutex_destroy(&processing); + pthread_cond_destroy(&needsProcess); #warning TODO deallocate Engines (or have possible issues) } @@ -66,6 +80,7 @@ void *_outputThread(void *arg) void *OutMgr::outputThread() { + pthread_mutex_lock(&close_m); //open up the default output if(!defaultOut->Start())//there should be a better failsafe cerr << "ERROR: The default Audio Output Failed to Open!" << endl; @@ -74,31 +89,21 @@ void *OutMgr::outputThread() running=true; init=true; bool doWait=false; - while(running) { - --numRequests; + while(running()) { - pthread_mutex_lock(&mutex); if(false) { cout << "Status: "; + pthread_mutex_lock(&mutex); cout << managedOuts.size() << "-"; cout << unmanagedOuts.size(); + pthread_mutex_unlock(&mutex); cout << " outs, "; cout << doWait; cout << " waits, "; cout << numRequests(); cout << " requests" << endl; } - pthread_mutex_unlock(&mutex); - doWait = (numRequests()<1); - - pthread_mutex_lock(&processing); - if(doWait) { - pthread_cond_wait(&needsProcess, &processing); - } - else - if(true) - cout << "Run Forest Run!" << endl; pthread_mutex_lock(&(master->mutex)); master->AudioOut(outl,outr); @@ -128,9 +133,19 @@ void *OutMgr::outputThread() cout << endl; pthread_mutex_unlock(&mutex); + //wait for next run + --numRequests; + doWait = (numRequests()<1); + pthread_mutex_lock(&processing); + if(doWait) { + pthread_cond_wait(&needsProcess, &processing); + pthread_mutex_unlock(&processing); + } + else + if(false) + cout << "Run Forest Run!" << endl; + } - pthread_mutex_lock(&close_m); - pthread_cond_signal(&close_cond); pthread_mutex_unlock(&close_m); return NULL; } @@ -154,7 +169,7 @@ void OutMgr::add(AudioOut *driver) { pthread_mutex_lock(&mutex); unmanagedOuts.push_back(driver); - if(running)//hotplug + if(running())//hotplug driver->Start(); pthread_mutex_unlock(&mutex); } diff --git a/src/Nio/OutMgr.h b/src/Nio/OutMgr.h @@ -44,7 +44,7 @@ class OutMgr void *outputThread(); private: - bool running; + Atomic<bool> running; bool init; //should hold outputs here that exist for the life of the OutMgr diff --git a/src/main.cpp b/src/main.cpp @@ -260,6 +260,7 @@ void initprogram() void exitprogram() { pthread_mutex_lock(&master->mutex); + delete sysOut; #ifndef DISABLE_GUI delete (ui);