Fix an infinite loop in S_StopEnvSound() that could occur if the audio thread happened to finish playing a voice in between checking if g_sounds[].voices[].id > FX_Ok and calling FX_StopSound(), exacerbated by improper std::atomic usage

git-svn-id: https://svn.eduke32.com/eduke32@7305 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
terminx 2019-01-12 00:21:58 +00:00
parent 6ca492918e
commit 97c2271b92

View file

@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "renderlayer.h" // for win_gethwnd() #include "renderlayer.h" // for win_gethwnd()
#include <atomic> #include <atomic>
#define DQSIZE 128 #define DQSIZE 256
int32_t g_numEnvSoundsPlaying, g_highestSoundIdx = 0; int32_t g_numEnvSoundsPlaying, g_highestSoundIdx = 0;
@ -79,7 +79,7 @@ void S_SoundStartup(void)
FX_SetReverseStereo(ud.config.ReverseStereo); FX_SetReverseStereo(ud.config.ReverseStereo);
FX_SetCallBack(S_Callback); FX_SetCallBack(S_Callback);
FX_SetPrintf(initprintf); FX_SetPrintf(OSD_Printf);
} }
void S_SoundShutdown(void) void S_SoundShutdown(void)
@ -377,9 +377,8 @@ void S_StopMusic(void)
void S_Cleanup(void) void S_Cleanup(void)
{ {
static uint32_t ldnum; static uint32_t ldnum;
uint32_t const odnum = dnum;
while (ldnum < odnum) while (ldnum < dnum)
{ {
uint32_t num = dq[ldnum++ & (DQSIZE - 1)]; uint32_t num = dq[ldnum++ & (DQSIZE - 1)];
@ -816,6 +815,8 @@ void S_StopEnvSound(int32_t num, int32_t i)
{ {
for (j=0; j<MAXSOUNDINSTANCES; ++j) for (j=0; j<MAXSOUNDINSTANCES; ++j)
{ {
S_Cleanup();
if ((i == -1 && g_sounds[num].voices[j].id > FX_Ok) || (i != -1 && g_sounds[num].voices[j].owner == i)) if ((i == -1 && g_sounds[num].voices[j].id > FX_Ok) || (i != -1 && g_sounds[num].voices[j].owner == i))
{ {
#ifdef DEBUGGINGAIDS #ifdef DEBUGGINGAIDS
@ -825,8 +826,8 @@ void S_StopEnvSound(int32_t num, int32_t i)
#endif #endif
if (g_sounds[num].voices[j].id > FX_Ok) if (g_sounds[num].voices[j].id > FX_Ok)
{ {
FX_StopSound(g_sounds[num].voices[j].id); if (FX_SoundActive(g_sounds[num].voices[j].id))
S_Cleanup(); FX_StopSound(g_sounds[num].voices[j].id);
break; break;
} }
} }
@ -861,8 +862,6 @@ void S_ChangeSoundPitch(int soundNum, int spriteNum, int pitchoffset)
void S_Update(void) void S_Update(void)
{ {
S_Cleanup();
if ((g_player[myconnectindex].ps->gm & (MODE_GAME|MODE_DEMO)) == 0) if ((g_player[myconnectindex].ps->gm & (MODE_GAME|MODE_DEMO)) == 0)
return; return;
@ -892,6 +891,8 @@ void S_Update(void)
if (g_sounds[sndnum].num == 0) if (g_sounds[sndnum].num == 0)
continue; continue;
S_Cleanup();
for (auto &voice : g_sounds[sndnum].voices) for (auto &voice : g_sounds[sndnum].voices)
{ {
int const spriteNum = voice.owner; int const spriteNum = voice.owner;
@ -919,7 +920,9 @@ void S_Callback(uint32_t num)
if ((int32_t)num == MUSIC_ID) if ((int32_t)num == MUSIC_ID)
return; return;
dq[dnum++ & (DQSIZE - 1)] = num; int const ldnum = dnum;
dq[ldnum & (DQSIZE - 1)] = num;
dnum++;
} }
void S_ClearSoundLocks(void) void S_ClearSoundLocks(void)