TSAGE: Fix deadlocks in audio code

Fixes Trac#6618, Trac#6638, Trac#7011.
This commit is contained in:
Colin Snover 2017-11-20 15:32:32 -06:00
parent 7fc9e381b8
commit fe45300891
2 changed files with 11 additions and 15 deletions

View File

@ -23,6 +23,7 @@
#include "audio/fmopl.h"
#include "audio/decoders/raw.h"
#include "common/config-manager.h"
#include "common/timer.h"
#include "audio/audiostream.h"
#include "tsage/core.h"
#include "tsage/globals.h"
@ -70,7 +71,7 @@ SoundManager::~SoundManager() {
}
sfTerminate();
// g_system->getTimerManager()->removeTimerProc(_sfUpdateCallback);
g_system->getTimerManager()->removeTimerProc(&sfSoundServer);
}
// Free any allocated voice type structures
@ -90,12 +91,7 @@ void SoundManager::postInit() {
g_saver->addLoadNotifier(&SoundManager::loadNotifier);
g_saver->addListener(this);
// I originally separated the sound manager update method into a separate thread, since
// it handles updates for both music and Fx. However, since Adlib updates also get done in a
// thread, and doesn't get too far ahead, I've left it to the AdlibSoundDriver class to
// call the update method, rather than having it be called separately
// g_system->getTimerManager()->installTimerProc(_sfUpdateCallback, 1000000 / SOUND_FREQUENCY, NULL, "tsageSoundUpdate");
g_system->getTimerManager()->installTimerProc(&sfSoundServer, 1000000 / CALLBACKS_PER_SECOND, NULL, "tsageSoundUpdate");
_sndmgrReady = true;
}
}
@ -378,7 +374,10 @@ void SoundManager::rethinkVoiceTypes() {
sfRethinkVoiceTypes();
}
void SoundManager::sfSoundServer() {
void SoundManager::sfSoundServer(void *) {
Common::StackLock slock1(SoundManager::sfManager()._serverDisabledMutex);
Common::StackLock slock2(SoundManager::sfManager()._serverSuspendedMutex);
if (sfManager()._needToRethink) {
sfRethinkVoiceTypes();
sfManager()._needToRethink = false;
@ -2871,13 +2870,13 @@ void AdlibSoundDriver::setPitch(int channel, int pitchBlend) {
}
void AdlibSoundDriver::write(byte reg, byte value) {
Common::StackLock lock(_queueMutex);
_portContents[reg] = value;
_queue.push(RegisterValue(reg, value));
}
void AdlibSoundDriver::flush() {
Common::StackLock slock(SoundManager::sfManager()._serverDisabledMutex);
Common::StackLock lock(_queueMutex);
while (!_queue.empty()) {
RegisterValue v = _queue.pop();
_opl->writeReg(v._regNum, v._value);
@ -3005,10 +3004,6 @@ void AdlibSoundDriver::setFrequency(int channel) {
}
void AdlibSoundDriver::onTimer() {
Common::StackLock slock1(SoundManager::sfManager()._serverDisabledMutex);
Common::StackLock slock2(SoundManager::sfManager()._serverSuspendedMutex);
SoundManager::sfSoundServer();
flush();
}

View File

@ -251,7 +251,7 @@ public:
static void sfDoAddToPlayList(Sound *sound);
static bool sfDoRemoveFromPlayList(Sound *sound);
static void sfDoUpdateVolume(Sound *sound);
static void sfSoundServer();
static void sfSoundServer(void *);
static void sfProcessFading();
static void sfUpdateVoiceStructs();
static void sfUpdateVoiceStructs2();
@ -458,6 +458,7 @@ private:
byte _portContents[256];
const byte *_patchData;
int _masterVolume;
Common::Mutex _queueMutex;
Common::Queue<RegisterValue> _queue;
bool _channelVoiced[ADLIB_CHANNEL_COUNT];