From b925b61654a8e48788a75e637d47b8f21ba634c0 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Fri, 16 Apr 2004 22:28:01 +0000 Subject: [PATCH] fix lock ordering all sounds are now deleted in the main thread --- stepmania/src/RageSound.cpp | 2 ++ stepmania/src/RageSound.h | 1 + stepmania/src/RageSoundManager.cpp | 22 ++++++++++++++-------- stepmania/src/RageSoundManager.h | 4 ++++ stepmania/src/RageSounds.cpp | 2 +- 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/stepmania/src/RageSound.cpp b/stepmania/src/RageSound.cpp index 87339445c6..4d9dfc5f64 100644 --- a/stepmania/src/RageSound.cpp +++ b/stepmania/src/RageSound.cpp @@ -519,7 +519,9 @@ bool RageSound::GetDataToPlay( int16_t *buffer, int size, int &sound_frame, int /* Indicate that a block of audio data has been written to the device. */ void RageSound::CommitPlayingPosition( int64_t frameno, int pos, int got_frames ) { + m_Mutex.Lock(); pos_map.Insert( frameno, pos, got_frames ); + m_Mutex.Unlock(); } /* Called by the mixer: return a block of sound data. diff --git a/stepmania/src/RageSound.h b/stepmania/src/RageSound.h index ec6d40cd3f..fea4c948e0 100644 --- a/stepmania/src/RageSound.h +++ b/stepmania/src/RageSound.h @@ -2,6 +2,7 @@ #define RAGE_SOUND_OBJ_H #include +#include "RageThreads.h" #include "RageTimer.h" #include "RageUtil_CircularBuffer.h" #include "RageSoundPosMap.h" diff --git a/stepmania/src/RageSoundManager.cpp b/stepmania/src/RageSoundManager.cpp index 88b2bfb3d2..aebe76c05f 100644 --- a/stepmania/src/RageSoundManager.cpp +++ b/stepmania/src/RageSoundManager.cpp @@ -161,9 +161,7 @@ void RageSoundManager::CommitPlayingPosition( int ID, int64_t frameno, int pos, RageSound *RageSoundManager::GetSoundByID( int ID ) { - /* You must lock this mutex before calling this function. If you don't, - * from any thread, the returned sound may be invalidated. */ - ASSERT( g_SoundManMutex.IsLockedByThisThread() ); + LockMut( g_SoundManMutex ); /* Find the sound with p.ID. */ set::iterator it; @@ -176,10 +174,6 @@ RageSound *RageSoundManager::GetSoundByID( int ID ) /* This is only called by RageSoundManager::Update. */ void RageSoundManager::FlushPosMapQueue() { - /* Lock, to make sure sounds returned by GetSoundByID remain valid until we're - * done with them. */ - LockMut(g_SoundManMutex); - queued_pos_map_t p; /* We don't need to lock to access pos_map_queue. */ @@ -260,6 +254,18 @@ set RageSoundManager::GetPlayingSounds() const return playing_sounds; } +void RageSoundManager::DeleteSound( RageSound *p ) +{ + /* Stop playing the sound. */ + p->StopPlaying(); + + /* Add it to owned_sounds. It'll be deleted the next time we come around + * to Update(). */ + g_SoundManMutex.Lock(); /* lock for access to owned_sounds */ + owned_sounds.insert( p ); + g_SoundManMutex.Unlock(); /* finished with owned_sounds */ +} + void RageSoundManager::StopPlayingSoundsForThisThread() { /* Lock to make sure sounds don't become invalidated below before we get to them. */ @@ -295,7 +301,7 @@ void RageSoundManager::GetCopies( RageSound &snd, vector &snds, boo g_SoundManMutex.Lock(); /* lock for access to all_sounds */ set sounds = all_sounds; - g_SoundManMutex.Unlock(); /* finished with owned_sounds */ + g_SoundManMutex.Unlock(); /* finished with all_sounds */ RageSound *parent = snd.GetOriginal(); diff --git a/stepmania/src/RageSoundManager.h b/stepmania/src/RageSoundManager.h index 994a9a3139..2e8fe6d805 100644 --- a/stepmania/src/RageSoundManager.h +++ b/stepmania/src/RageSoundManager.h @@ -53,6 +53,10 @@ public: int GetDriverSampleRate( int rate ) const; set GetPlayingSounds() const; + /* When deleting a sound from any thread except the one calling Update(), this + * must be used to prevent race conditions. */ + void DeleteSound( RageSound *p ); + void PlayOnce( CString sPath ); RageSound *PlaySound( RageSound &snd, const RageSoundParams *params ); diff --git a/stepmania/src/RageSounds.cpp b/stepmania/src/RageSounds.cpp index aa8a5b342b..707b0d5112 100644 --- a/stepmania/src/RageSounds.cpp +++ b/stepmania/src/RageSounds.cpp @@ -53,7 +53,7 @@ struct MusicPlaying ~MusicPlaying() { - delete m_Music; + SOUNDMAN->DeleteSound( m_Music ); } };