Handle pauseAll and resumeAll completely in thread now. Avoids a crash

(caused by pauseAll trying to pause a sfx that is still in the list of
all sfx, but has a delete command already queued up).
This commit is contained in:
hiker 2014-10-17 16:26:15 +11:00
parent 383cbef14d
commit 403702d6bb
2 changed files with 32 additions and 9 deletions

View File

@ -233,7 +233,7 @@ void SFXManager::update(float dt)
*/ */
void SFXManager::stopThread() void SFXManager::stopThread()
{ {
queue(SFX_EXIT, NULL); queue(SFX_EXIT);
// Make sure the thread wakes up. // Make sure the thread wakes up.
pthread_cond_signal(&m_cond_request); pthread_cond_signal(&m_cond_request);
} // stopThread } // stopThread
@ -291,6 +291,8 @@ void* SFXManager::mainLoop(void *obj)
case SFX_DELETE: { case SFX_DELETE: {
me->deleteSFX(current->m_sfx); break; me->deleteSFX(current->m_sfx); break;
} }
case SFX_PAUSE_ALL: me->reallyPauseAllNow(); break;
case SFX_RESUME_ALL: me->reallyResumeAllNow(); break;
case SFX_LISTENER: me->reallyPositionListenerNow(); break; case SFX_LISTENER: me->reallyPositionListenerNow(); break;
case SFX_UPDATE_MUSIC: music_manager->update( case SFX_UPDATE_MUSIC: music_manager->update(
current->m_parameter.getX()); break; current->m_parameter.getX()); break;
@ -610,24 +612,41 @@ void SFXManager::deleteSFX(SFXBase *sfx)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
/** Pauses all looping SFXs. Non-looping SFX will be finished, since it's /** Pauses all looping SFXs. Non-looping SFX will be finished, since it's
* otherwise not possible to determine which SFX must be resumed (i.e. were * otherwise not possible to determine which SFX must be resumed (i.e. were
* actually playing at the time pause was called. * actually playing at the time pause was called).
*/ */
void SFXManager::pauseAll() void SFXManager::pauseAll()
{
queue(SFX_PAUSE_ALL);
} // pauseAll
//----------------------------------------------------------------------------
/** Pauses all looping SFXs. Non-looping SFX will be finished, since it's
* otherwise not possible to determine which SFX must be resumed (i.e. were
* actually playing at the time pause was called.
*/
void SFXManager::reallyPauseAllNow()
{ {
m_all_sfx.lock(); m_all_sfx.lock();
for (std::vector<SFXBase*>::iterator i= m_all_sfx.getData().begin(); for (std::vector<SFXBase*>::iterator i= m_all_sfx.getData().begin();
i!=m_all_sfx.getData().end(); i++) i!=m_all_sfx.getData().end(); i++)
{ {
(*i)->pause(); (*i)->reallyPauseNow();
} // for i in m_all_sfx } // for i in m_all_sfx
m_all_sfx.unlock(); m_all_sfx.unlock();
} // pauseAll } // pauseAll
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
/** /** Resumes all paused SFXs. If sound is disabled, does nothing.
* Resumes all paused SFXs. If sound is disabled, does nothing.
*/ */
void SFXManager::resumeAll() void SFXManager::resumeAll()
{
queue(SFX_RESUME_ALL);
} // resumeAll
//----------------------------------------------------------------------------
/** Resumes all paused SFXs. If sound is disabled, does nothing.
*/
void SFXManager::reallyResumeAllNow()
{ {
// ignore unpausing if sound is disabled // ignore unpausing if sound is disabled
if (!sfxAllowed()) return; if (!sfxAllowed()) return;
@ -636,7 +655,7 @@ void SFXManager::resumeAll()
for (std::vector<SFXBase*>::iterator i =m_all_sfx.getData().begin(); for (std::vector<SFXBase*>::iterator i =m_all_sfx.getData().begin();
i!=m_all_sfx.getData().end(); i++) i!=m_all_sfx.getData().end(); i++)
{ {
(*i)->resume(); (*i)->reallyResumeNow();
} // for i in m_all_sfx } // for i in m_all_sfx
m_all_sfx.unlock(); m_all_sfx.unlock();
} // resumeAll } // resumeAll
@ -729,7 +748,7 @@ void SFXManager::positionListener(const Vec3 &position, const Vec3 &front,
m_listener_front = front; m_listener_front = front;
m_listener_up = up; m_listener_up = up;
m_listener_position.unlock(); m_listener_position.unlock();
queue(SFX_LISTENER, NULL); queue(SFX_LISTENER);
} // positionListener } // positionListener
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -65,7 +65,9 @@ public:
SFX_PLAY = 1, SFX_PLAY = 1,
SFX_STOP, SFX_STOP,
SFX_PAUSE, SFX_PAUSE,
SFX_PAUSE_ALL,
SFX_RESUME, SFX_RESUME,
SFX_RESUME_ALL,
SFX_DELETE, SFX_DELETE,
SFX_SPEED, SFX_SPEED,
SFX_POSITION, SFX_POSITION,
@ -181,7 +183,7 @@ private:
public: public:
static void create(); static void create();
static void destroy(); static void destroy();
void queue(SFXCommands command, SFXBase *sfx); void queue(SFXCommands command, SFXBase *sfx=NULL);
void queue(SFXCommands command, SFXBase *sfx, float f); void queue(SFXCommands command, SFXBase *sfx, float f);
void queue(SFXCommands command, SFXBase *sfx, const Vec3 &p); void queue(SFXCommands command, SFXBase *sfx, const Vec3 &p);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -214,7 +216,9 @@ public:
void deleteSFXMapping(const std::string &name); void deleteSFXMapping(const std::string &name);
void pauseAll(); void pauseAll();
void reallyPauseAllNow();
void resumeAll(); void resumeAll();
void reallyResumeAllNow();
void update(float dt); void update(float dt);
bool soundExist(const std::string &name); bool soundExist(const std::string &name);
void setMasterSFXVolume(float gain); void setMasterSFXVolume(float gain);