[Scummvm-cvs-logs] SF.net SVN: scummvm:[54241] scummvm/trunk/engines/lastexpress/game

littleboy at users.sourceforge.net littleboy at users.sourceforge.net
Mon Nov 15 13:48:55 CET 2010


Revision: 54241
          http://scummvm.svn.sourceforge.net/scummvm/?rev=54241&view=rev
Author:   littleboy
Date:     2010-11-15 12:48:54 +0000 (Mon, 15 Nov 2010)

Log Message:
-----------
LASTEXPRESS: Protect sound queue accesses with mutex

Sound entries were being streamed before the data was fully loaded
and queue addition/removal could happen while the sound timer was
going through the queue (reported by digitall).

Modified Paths:
--------------
    scummvm/trunk/engines/lastexpress/game/sound.cpp
    scummvm/trunk/engines/lastexpress/game/sound.h

Modified: scummvm/trunk/engines/lastexpress/game/sound.cpp
===================================================================
--- scummvm/trunk/engines/lastexpress/game/sound.cpp	2010-11-15 06:35:51 UTC (rev 54240)
+++ scummvm/trunk/engines/lastexpress/game/sound.cpp	2010-11-15 12:48:54 UTC (rev 54241)
@@ -133,6 +133,7 @@
 // Timer
 //////////////////////////////////////////////////////////////////////////
 void SoundManager::handleTimer() {
+	_mutex.lock();
 
 	for (Common::List<SoundEntry *>::iterator i = _cache.begin(); i != _cache.end(); ++i) {
 		SoundEntry *entry = (*i);
@@ -142,17 +143,20 @@
 			continue;
 		} else if (!entry->isStreamed) {
 			entry->isStreamed = true;
+
+			// TODO: stream any sound in the queue after filtering
 			_soundStream->load(entry->stream);
 		}
 	}
 
-	// TODO: stream any sound in the queue after filtering
+	_mutex.unlock();
 }
 
 //////////////////////////////////////////////////////////////////////////
 // Sound queue management
 //////////////////////////////////////////////////////////////////////////
 void SoundManager::updateQueue() {
+	// TODO add mutex lock!
 	//warning("Sound::unknownFunction1: not implemented!");
 }
 
@@ -160,36 +164,48 @@
 	if (!type2)
 		type2 = type1;
 
+	_mutex.lock();
+
 	for (Common::List<SoundEntry *>::iterator i = _cache.begin(); i != _cache.end(); ++i) {
 		if ((*i)->type != type1 && (*i)->type != type2)
 			resetEntry(*i);
 	}
+
+	_mutex.unlock();
 }
 
 void SoundManager::removeFromQueue(EntityIndex entity) {
+	_mutex.lock();
+
 	SoundEntry *entry = getEntry(entity);
-
 	if (entry)
 		resetEntry(entry);
+
+	_mutex.unlock();
 }
 
 void SoundManager::removeFromQueue(Common::String filename) {
+	_mutex.lock();
+
 	SoundEntry *entry = getEntry(filename);
-
 	if (entry)
 		resetEntry(entry);
+
+	_mutex.unlock();
 }
 
 void SoundManager::clearQueue() {
 	_flag |= 4;
 
-	// Wait a while for a flag to be set
-	for (int i = 0; i < 3000000; i++)
-		if (_flag & 8)
-			break;
+	// FIXME: Wait a while for a flag to be set
+	//for (int i = 0; i < 3000000; i++)
+	//	if (_flag & 8)
+	//		break;
 
 	_flag |= 8;
 
+	_mutex.lock();
+
 	for (Common::List<SoundEntry *>::iterator i = _cache.begin(); i != _cache.end(); ++i) {
 		SoundEntry *entry = (*i);
 
@@ -200,26 +216,39 @@
 		i = _cache.reverse_erase(i);
 	}
 
+	_mutex.unlock();
+
 	updateSubtitles();
 }
 
 bool SoundManager::isBuffered(EntityIndex entity) {
-	return (getEntry(entity) != NULL);
+	_mutex.lock();
+
+	bool buffered = (getEntry(entity) != NULL);	
+
+	_mutex.unlock();
+
+	return buffered;
 }
 
 bool SoundManager::isBuffered(Common::String filename, bool testForEntity) {
+	_mutex.lock();
+
 	SoundEntry *entry = getEntry(filename);
 
+	bool ret = (entry != NULL);
 	if (testForEntity)
-		return entry != NULL && !entry->entity;
+		ret = ret && !entry->entity;
 
-	return (entry != NULL);
+	_mutex.unlock();
+
+	return ret;
 }
 
 //////////////////////////////////////////////////////////////////////////
 // Entry
 //////////////////////////////////////////////////////////////////////////
-void SoundManager::setupEntry(SoundEntry *entry, Common::String name, FlagType flag, int a4) {
+void SoundManager::setupEntry(SoundEntry *entry, Common::String name, FlagType flag, int a4) {	
 	if (!entry)
 		error("SoundManager::setupEntry: Invalid entry!");
 
@@ -323,8 +352,12 @@
 }
 
 void SoundManager::clearStatus() {
+	_mutex.lock();
+
 	for (Common::List<SoundEntry *>::iterator i = _cache.begin(); i != _cache.end(); ++i)
 		(*i)->status.status |= kSoundStatusClear3;
+
+	_mutex.unlock();
 }
 
 void SoundManager::loadSoundData(SoundEntry *entry, Common::String name) {
@@ -343,7 +376,7 @@
 	}
 }
 
-void SoundManager::resetEntry(SoundEntry *entry) const {
+void SoundManager::resetEntry(SoundEntry *entry) {
 	entry->status.status |= kSoundStatusRemoved;
 	entry->entity = kEntityPlayer;
 
@@ -383,7 +416,6 @@
 
 void SoundManager::updateEntry(SoundEntry *entry, uint value) const {
 	if (!(entry->status.status3 & 64)) {
-
 		int value2 = value;
 
 		entry->status.status |= kSoundStatus_100000;
@@ -418,26 +450,35 @@
 }
 
 void SoundManager::processEntry(EntityIndex entity) {
+	_mutex.lock();
+
 	SoundEntry *entry = getEntry(entity);
-
 	if (entry) {
 		updateEntry(entry, 0);
 		entry->entity = kEntityPlayer;
 	}
+
+	_mutex.unlock();
 }
 
 void SoundManager::processEntry(SoundType type) {
+	_mutex.lock();
+
 	SoundEntry *entry = getEntry(type);
-
 	if (entry)
 		updateEntry(entry, 0);
+
+	_mutex.unlock();
 }
 
 void SoundManager::setupEntry(SoundType type, EntityIndex index) {
+	_mutex.lock();
+
 	SoundEntry *entry = getEntry(type);
-
 	if (entry)
 		entry->entity = index;
+
+	_mutex.unlock();
 }
 
 void SoundManager::processEntry(Common::String filename) {
@@ -457,12 +498,16 @@
 }
 
 uint32 SoundManager::getEntryTime(EntityIndex index) {
+	_mutex.lock();
+
+	uint32 time = 0;
 	SoundEntry *entry = getEntry(index);
+	if (entry)
+		time = entry->time;
 
-	if (!entry)
-		return 0;
+	_mutex.unlock();
 
-	return entry->time;
+	return time;
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -470,6 +515,7 @@
 //////////////////////////////////////////////////////////////////////////
 
 void SoundManager::unknownFunction4() {
+	// TODO: Add mutex ?
 	warning("Sound::unknownFunction4: not implemented!");
 }
 
@@ -517,6 +563,8 @@
 	uint32 numEntries = count();
 	s.syncAsUint32LE(numEntries);
 
+	_mutex.lock();
+
 	// Save or load each entry data
 	if (s.isSaving()) {
 		for (Common::List<SoundEntry *>::iterator i = _cache.begin(); i != _cache.end(); ++i) {
@@ -550,14 +598,24 @@
 		warning("Sound::saveLoadWithSerializer: not implemented!");
 		s.skip(numEntries * 64);
 	}
+
+	_mutex.unlock();
 }
 
+
+// FIXME: We probably need another mutex here to protect during the whole savegame process
+// as we could have removed an entry between the time we check the count and the time we
+// save the entries
 uint32 SoundManager::count() {
+	_mutex.lock();
+
 	uint32 numEntries = 0;
 	for (Common::List<SoundEntry *>::iterator i = _cache.begin(); i != _cache.end(); ++i)
 		if ((*i)->name2.matchString("NISSND?"))
 			++numEntries;
 
+	_mutex.unlock();
+
 	return numEntries;
 }
 
@@ -579,8 +637,11 @@
 			getSavePoints()->push(kEntityPlayer, entity, kActionEndSound);
 }
 
-SoundManager::SoundType SoundManager::playSoundWithSubtitles(Common::String filename, FlagType flag, EntityIndex entity, byte a4) {
+bool SoundManager::playSoundWithSubtitles(Common::String filename, FlagType flag, EntityIndex entity, byte a4) {
 	SoundEntry *entry = new SoundEntry();
+
+	_mutex.lock();
+
 	setupEntry(entry, filename, flag, 30);
 	entry->entity = entity;
 
@@ -596,7 +657,11 @@
 		updateEntryState(entry);
 	}
 
-	return entry->type;
+	bool isPlaying = (entry->type != NULL);
+
+	_mutex.unlock();
+
+	return isPlaying;
 }
 
 void SoundManager::playSoundEvent(EntityIndex entity, byte action, byte a3) {
@@ -1715,6 +1780,7 @@
 // Subtitles
 //////////////////////////////////////////////////////////////////////////
 void SoundManager::updateSubtitles() {
+	// TODO: Add mutex ?
 	//warning("SoundManager::updateSubtitles: not implemented!");
 }
 

Modified: scummvm/trunk/engines/lastexpress/game/sound.h
===================================================================
--- scummvm/trunk/engines/lastexpress/game/sound.h	2010-11-15 06:35:51 UTC (rev 54240)
+++ scummvm/trunk/engines/lastexpress/game/sound.h	2010-11-15 12:48:54 UTC (rev 54241)
@@ -74,6 +74,7 @@
 #include "lastexpress/helpers.h"
 
 #include "common/list.h"
+#include "common/mutex.h"
 #include "common/system.h"
 #include "common/serializer.h"
 
@@ -171,7 +172,7 @@
 
 	// Sound playing
 	void playSound(EntityIndex entity, Common::String filename, FlagType flag = kFlagInvalid, byte a4 = 0);
-	SoundType playSoundWithSubtitles(Common::String filename, FlagType flag, EntityIndex entity, byte a4 = 0);
+	bool playSoundWithSubtitles(Common::String filename, FlagType flag, EntityIndex entity, byte a4 = 0);
 	void playSoundEvent(EntityIndex entity, byte action, byte a3 = 0);
 	void playDialog(EntityIndex entity, EntityIndex entityDialog, FlagType flag, byte a4);
 	void playSteam(CityIndex index);
@@ -306,6 +307,8 @@
 	// Sound stream
 	StreamedSound *_soundStream;
 
+	Common::Mutex _mutex;
+
 	// Unknown data
 	uint32 _data0;
 	uint32 _data1;
@@ -313,7 +316,6 @@
 	uint32 _flag;
 
 	// Filters
-
 	int32 _buffer[2940];    ///< Static sound buffer
 
 	// Compartment warnings by Mertens or Coudert
@@ -337,7 +339,7 @@
 
 	void updateEntry(SoundEntry *entry, uint value) const;
 	void updateEntryState(SoundEntry *entry) const ;
-	void resetEntry(SoundEntry *entry) const;
+	void resetEntry(SoundEntry *entry);
 	void removeEntry(SoundEntry *entry);
 
 	// Subtitles


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list