Skip to content

Commit ed9b1a0

Browse files
committed
fix(milesaudiomanager): Prevent multithread crashing in MilesAudioManager (#2718)
1 parent 333467f commit ed9b1a0

4 files changed

Lines changed: 339 additions & 207 deletions

File tree

Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "Common/AsciiString.h"
2424
#include "Common/GameAudio.h"
2525
#include "mss/mss.h"
26+
#include "mutex.h"
2627

2728
class AudioEventRTS;
2829

@@ -39,7 +40,8 @@ enum PlayingAudioType CPP_11(: Int)
3940
enum PlayingStatus CPP_11(: Int)
4041
{
4142
PS_Playing,
42-
PS_Stopped,
43+
PS_Stopping, ///< Is about to be stopped
44+
PS_Stopped, ///< Is about to be released
4345
};
4446

4547
enum PlayingWhich CPP_11(: Int)
@@ -63,8 +65,8 @@ struct PlayingAudio
6365
void *m_file; // The file that was opened to play this
6466
PlayingAudioType m_type;
6567
volatile PlayingStatus m_status; // This member is adjusted by another running thread.
66-
Int m_framesFaded;
67-
Bool m_requestStop;
68+
Short m_framesFaded;
69+
Bool m_fade;
6870
Bool m_cleanupAudioEventRTS;
6971

7072
PlayingAudio()
@@ -74,9 +76,11 @@ struct PlayingAudio
7476
, m_type(PAT_INVALID)
7577
, m_status(PS_Playing)
7678
, m_framesFaded(0)
77-
, m_requestStop(false)
79+
, m_fade(false)
7880
, m_cleanupAudioEventRTS(true)
7981
{}
82+
83+
static_assert(sizeof(m_status) == sizeof(long), "Must be size of long, because it is used with Interlocked functions");
8084
};
8185

8286
struct ProviderInfo
@@ -258,6 +262,8 @@ class MilesAudioManager : public AudioManager
258262
PlayingAudio *allocatePlayingAudio();
259263
void releaseMilesHandles( PlayingAudio *release );
260264
void releasePlayingAudio( PlayingAudio *release );
265+
void stopPlayingAudio( PlayingAudio *release );
266+
void fadePlayingAudio( PlayingAudio *playing );
261267

262268
PlayingAudio *findActiveMusic( const AsciiString *trackName = nullptr );
263269
const PlayingAudio *findActiveMusic( const AsciiString* trackName = nullptr ) const;
@@ -307,6 +313,13 @@ class MilesAudioManager : public AudioManager
307313
// Currently fading music. We just let it finish fading, then release it.
308314
std::list<PlayingAudio *> m_fadingAudio;
309315

316+
// TheSuperHackers @fix Erasing from PlayingAudio lists on main thread is not safe when when the MSS Timer thread
317+
// needs to iterate the same lists. The critical sections are used to guard writes that will invalidate iterators.
318+
CriticalSectionClass m_playingSoundsCS;
319+
CriticalSectionClass m_playing3DSoundsCS;
320+
CriticalSectionClass m_playingStreamsCS;
321+
CriticalSectionClass m_fadingAudioCS;
322+
310323
AudioFileCache *m_audioCache;
311324
PlayingAudio *m_binkHandle;
312325
UnsignedInt m_num2DSamples;

0 commit comments

Comments
 (0)