[Scummvm-cvs-logs] scummvm master -> 7f8a69d6fc44ca5515a91f29ce5451c12f85daa5

athrxx athrxx at scummvm.org
Mon May 30 01:51:17 CEST 2011


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
7f8a69d6fc FM-TOWNS AUDIO: fix destructors (thread safety)


Commit: 7f8a69d6fc44ca5515a91f29ce5451c12f85daa5
    https://github.com/scummvm/scummvm/commit/7f8a69d6fc44ca5515a91f29ce5451c12f85daa5
Author: athrxx (athrxx at scummvm.org)
Date: 2011-05-29T16:48:59-07:00

Commit Message:
FM-TOWNS AUDIO: fix destructors (thread safety)

Changed paths:
    audio/softsynth/fmtowns_pc98/towns_audio.cpp
    audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp
    audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
    audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h



diff --git a/audio/softsynth/fmtowns_pc98/towns_audio.cpp b/audio/softsynth/fmtowns_pc98/towns_audio.cpp
index 42a8252..efc9f9f 100644
--- a/audio/softsynth/fmtowns_pc98/towns_audio.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_audio.cpp
@@ -103,12 +103,11 @@ private:
 
 class TownsAudioInterfaceInternal : public TownsPC98_FmSynth {
 public:
-	TownsAudioInterfaceInternal(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
+	TownsAudioInterfaceInternal(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
 	~TownsAudioInterfaceInternal();
 
-	static TownsAudioInterfaceInternal *addNewRef(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
-	static void releaseRef();
-	bool checkPluginDriver(TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
+	static TownsAudioInterfaceInternal *addNewRef(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
+	static void releaseRef(TownsAudioInterface *owner);
 
 	bool init();
 
@@ -122,6 +121,9 @@ public:
 	void setSoundEffectChanMask(int mask);
 
 private:
+	bool assignPluginDriver(TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
+	void removePluginDriver(TownsAudioInterface *owner);
+
 	void nextTickEx(int32 *buffer, uint32 bufferSize);
 
 	void timerCallbackA();
@@ -239,6 +241,7 @@ private:
 	int _pcmSfxChanMask;
 
 	TownsAudioInterfacePluginDriver *_drv;
+	void *_drvOwner;
 	bool _ready;
 
 	static TownsAudioInterfaceInternal *_refInstance;
@@ -252,10 +255,10 @@ private:
 	static const uint16 _pcmPhase2[];
 };
 
-TownsAudioInterfaceInternal::TownsAudioInterfaceInternal(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) : 
+TownsAudioInterfaceInternal::TownsAudioInterfaceInternal(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) : 
 	TownsPC98_FmSynth(mixer, kTypeTowns, externalMutexHandling),
 	_fmInstruments(0), _pcmInstruments(0), _pcmChan(0), _waveTables(0), _waveTablesTotalDataSize(0),
-	_baserate(55125.0f / (float)mixer->getOutputRate()), _tickLength(0), _timer(0), _drv(driver),
+	_baserate(55125.0f / (float)mixer->getOutputRate()), _tickLength(0), _timer(0), _drv(driver), _drvOwner(owner),
 	_pcmSfxChanMask(0),	_musicVolume(Audio::Mixer::kMaxMixerVolume), _sfxVolume(Audio::Mixer::kMaxMixerVolume),
 	_outputVolumeFlags(0), _pcmChanOut(0), _pcmChanReserved(0), _pcmChanKeyPressed(0),
 	_pcmChanEffectPlaying(0), _pcmChanKeyPlaying(0), _fmChanPlaying(0), 
@@ -388,6 +391,8 @@ TownsAudioInterfaceInternal::~TownsAudioInterfaceInternal() {
 	_ready = false;
 	deinit();
 
+	Common::StackLock lock(_mutex);
+
 	delete[] _fmSaveReg[0];
 	delete[] _fmSaveReg[1];
 	delete[] _fmInstruments;
@@ -396,45 +401,33 @@ TownsAudioInterfaceInternal::~TownsAudioInterfaceInternal() {
 	delete[] _pcmChan;
 }
 
-TownsAudioInterfaceInternal *TownsAudioInterfaceInternal::addNewRef(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) {
+TownsAudioInterfaceInternal *TownsAudioInterfaceInternal::addNewRef(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) {
 	_refCount++;
 	if (_refCount == 1 && _refInstance == 0)
-		_refInstance = new TownsAudioInterfaceInternal(mixer, driver, externalMutexHandling);
+		_refInstance = new TownsAudioInterfaceInternal(mixer, owner, driver, externalMutexHandling);
 	else if (_refCount < 2 || _refInstance == 0)
 		error("TownsAudioInterfaceInternal::addNewRef(): Internal reference management failure");
-	else if (!_refInstance->checkPluginDriver(driver, externalMutexHandling))
+	else if (!_refInstance->assignPluginDriver(owner, driver, externalMutexHandling))
 		error("TownsAudioInterfaceInternal::addNewRef(): Plugin driver conflict");
 
 	return _refInstance;
 }
 
-void TownsAudioInterfaceInternal::releaseRef() {
+void TownsAudioInterfaceInternal::releaseRef(TownsAudioInterface *owner) {
 	if (!_refCount)
 		return;
 
 	_refCount--;
 	
-	if (!_refCount) {
+	if (_refCount) {
+		if (_refInstance)
+			_refInstance->removePluginDriver(owner);
+	} else {
 		delete _refInstance;
 		_refInstance = 0;
 	}
 }
 
-bool TownsAudioInterfaceInternal::checkPluginDriver(TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) {
-	if (_refCount <= 1)
-		return true;
-
-	if (_drv) {
-		if (driver && driver != _drv)
-			return false;
-	} else {
-		_drv = driver;
-		_externalMutex = externalMutexHandling;
-	}
-
-	return true;
-}
-
 bool TownsAudioInterfaceInternal::init() {
 	if (_ready)
 		return true;
@@ -501,6 +494,30 @@ void TownsAudioInterfaceInternal::setSoundEffectChanMask(int mask) {
 	setVolumeChannelMasks(~mask, mask);
 }
 
+bool TownsAudioInterfaceInternal::assignPluginDriver(TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) {
+	if (_refCount <= 1)
+		return true;
+
+	if (_drv) {
+		if (driver && driver != _drv)
+			return false;
+	} else {
+		Common::StackLock lock(_mutex);
+		_drv = driver;
+		_drvOwner = owner;
+		_externalMutex = externalMutexHandling;
+	}
+
+	return true;
+}
+
+void TownsAudioInterfaceInternal::removePluginDriver(TownsAudioInterface *owner) {
+	if (_drvOwner == owner) {
+		Common::StackLock lock(_mutex);
+		_drv = 0;
+	}
+}
+
 void TownsAudioInterfaceInternal::nextTickEx(int32 *buffer, uint32 bufferSize) {
 	if (!_ready)
 		return;
@@ -1856,11 +1873,11 @@ void TownsAudio_WaveTable::clear() {
 }
 
 TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) {
-	_intf = TownsAudioInterfaceInternal::addNewRef(mixer, driver, externalMutexHandling);
+	_intf = TownsAudioInterfaceInternal::addNewRef(mixer, this, driver, externalMutexHandling);
 }
 
 TownsAudioInterface::~TownsAudioInterface() {
-	TownsAudioInterfaceInternal::releaseRef();
+	TownsAudioInterfaceInternal::releaseRef(this);
 	_intf = 0;
 }
 
diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp
index ee20068..49fe97c 100644
--- a/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp
@@ -1054,6 +1054,8 @@ TownsPC98_AudioDriver::~TownsPC98_AudioDriver() {
 	_ready = false;
 	deinit();
 
+	Common::StackLock lock(_mutex);
+
 	if (_channels) {
 		for (int i = 0; i < _numChan; i++)
 			delete _channels[i];
diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
index f4dd3cf..63007ba 100644
--- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
@@ -875,6 +875,8 @@ TownsPC98_FmSynth::~TownsPC98_FmSynth() {
 	if (_ready)
 		deinit();
 
+	Common::StackLock lock(_mutex);
+
 	delete _ssg;
 #ifndef DISABLE_PC98_RHYTHM_CHANNEL
 	delete _prc;
@@ -1166,7 +1168,7 @@ int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) {
 					
 					(this->*_timers[i].cb)();
 
-					if (_ready && !locked && _externalMutex) {
+					if (!locked && _externalMutex) {
 						_mutex.lock();
 						locked = true;
 					}
@@ -1240,6 +1242,10 @@ void TownsPC98_FmSynth::deinit() {
 	_timers[0].cb = _timers[1].cb = &TownsPC98_FmSynth::idleTimerCallback;
 }
 
+void TownsPC98_FmSynth::toggleRegProtection(bool prot) {
+	_regProtectionFlag = prot;
+}
+
 uint8 TownsPC98_FmSynth::readSSGStatus() {
 	return _ssg->chanEnable();
 }
diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h
index 50a05f9..4f81fa9 100644
--- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h
+++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h
@@ -80,17 +80,15 @@ protected:
 	// additional output that has to be inserted into the buffer.
 	virtual void nextTickEx(int32 *buffer, uint32 bufferSize) {}
 
-	void toggleRegProtection(bool prot) {
-		_regProtectionFlag = prot;
-	}
+	void toggleRegProtection(bool prot);
 	uint8 readSSGStatus();
 
 	virtual void timerCallbackA() = 0;
 	virtual void timerCallbackB() = 0;
 
-	// The audio driver can store and apply two different audio settings
+	// The audio driver can store and apply two different volume settings
 	// (usually for music and sound effects). The channel mask will determine
-	// which channels get effected by the setting. The first bits will be
+	// which channels get effected by which setting. The first bits will be
 	// the normal fm channels, the next bits the ssg channels and the final
 	// bit the rhythm channel.
 	void setVolumeIntern(int volA, int volB);






More information about the Scummvm-git-logs mailing list