From 6c33b4ed284eabebc1077ef4093502b150ec71b8 Mon Sep 17 00:00:00 2001 From: Charles Pigott Date: Wed, 21 Jul 2021 10:32:33 +0100 Subject: Fix #8335: Race condition in music mixer (#9450) --- src/mixer.cpp | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/mixer.cpp b/src/mixer.cpp index d892a573c..b9b20fccf 100644 --- a/src/mixer.cpp +++ b/src/mixer.cpp @@ -9,12 +9,13 @@ #include "stdafx.h" #include +#include #include "core/math_func.hpp" #include "framerate_type.h" #include "settings_type.h" #include "safeguards.h" -#include "mixer.h" +#include "mixer.h" struct MixerChannel { bool active; @@ -39,6 +40,7 @@ static MixerChannel _channels[8]; static uint32 _play_rate = 11025; static uint32 _max_size = UINT_MAX; static MxStreamCallback _music_stream = nullptr; +static std::mutex _music_stream_mutex; /** * The theoretical maximum volume for a single sound sample. Multiple sound @@ -152,8 +154,11 @@ void MxMixSamples(void *buffer, uint samples) /* Clear the buffer */ memset(buffer, 0, sizeof(int16) * 2 * samples); - /* Fetch music if a sampled stream is available */ - if (_music_stream) _music_stream((int16*)buffer, samples); + { + std::lock_guard lock{ _music_stream_mutex }; + /* Fetch music if a sampled stream is available */ + if (_music_stream) _music_stream((int16*)buffer, samples); + } /* Apply simple x^3 scaling to master effect volume. This increases the * perceived difference in loudness to better match expectations. effect_vol @@ -227,22 +232,24 @@ void MxSetChannelVolume(MixerChannel *mc, uint volume, float pan) void MxActivateChannel(MixerChannel *mc) { mc->active = true; -} - -/** - * Set source of PCM music - * @param music_callback Function that will be called to fill sample buffers with music data. - * @return Sample rate of mixer, which the buffers supplied to the callback must be rendered at. - */ -uint32 MxSetMusicSource(MxStreamCallback music_callback) -{ - _music_stream = music_callback; - return _play_rate; +} + +/** + * Set source of PCM music + * @param music_callback Function that will be called to fill sample buffers with music data. + * @return Sample rate of mixer, which the buffers supplied to the callback must be rendered at. + */ +uint32 MxSetMusicSource(MxStreamCallback music_callback) +{ + std::lock_guard lock{ _music_stream_mutex }; + _music_stream = music_callback; + return _play_rate; } bool MxInitialize(uint rate) { + std::lock_guard lock{ _music_stream_mutex }; _play_rate = rate; _max_size = UINT_MAX / _play_rate; _music_stream = nullptr; /* rate may have changed, any music source is now invalid */ -- cgit v1.2.3