Skip to content

Commit

Permalink
fix potential infinite loop in ISound::Initialize
Browse files Browse the repository at this point in the history
make QTPFS' cache-update loops faster
  • Loading branch information
rtri committed Jul 18, 2015
1 parent 9b7d6f1 commit a8ba4cc
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 47 deletions.
46 changes: 41 additions & 5 deletions rts/Sim/Path/QTPFS/NodeLayer.cpp
Expand Up @@ -255,59 +255,87 @@ void QTPFS::NodeLayer::ExecNodeNeighborCacheUpdate(unsigned int currFrameNum, un
const int xmin = (xoff + 0 ), zmin = (zoff + 0 );
const int xmax = std::min(xmin + SQUARE_SIZE, mapDims.mapx >> 1), zmax = std::min(zmin + SQUARE_SIZE, mapDims.mapy >> 1);

for (int z = zmin; z < zmax; z++) {
for (int z = zmin; z < zmax; ) {
unsigned int zspan = zsize;

for (int x = xmin; x < xmax; ) {
n = nodeGrid[z * xsize + x];
x = n->xmax();

zspan = std::min(zspan, n->zmax() - z);
zspan = std::max(zspan, 1u);

n->SetMagicNumber(currMagicNum);
n->GetNeighbors(nodeGrid);
}

z += zspan;
}
}
{
// top-right quadrant: [mapDims.mapx >> 1, mapDims.mapx) x [0, mapDims.mapy >> 1)
const int xmin = (xoff + (mapDims.mapx >> 1)), zmin = (zoff + 0 );
const int xmax = std::min(xmin + SQUARE_SIZE, mapDims.mapx ), zmax = std::min(zmin + SQUARE_SIZE, mapDims.mapy >> 1);

for (int z = zmin; z < zmax; z++) {
for (int z = zmin; z < zmax; ) {
unsigned int zspan = zsize;

for (int x = xmin; x < xmax; ) {
n = nodeGrid[z * xsize + x];
x = n->xmax();

zspan = std::min(zspan, n->zmax() - z);
zspan = std::max(zspan, 1u);

n->SetMagicNumber(currMagicNum);
n->GetNeighbors(nodeGrid);
}

z += zspan;
}
}
{
// bottom-right quadrant: [mapDims.mapx >> 1, mapDims.mapx) x [mapDims.mapy >> 1, mapDims.mapy)
const int xmin = (xoff + (mapDims.mapx >> 1)), zmin = (zoff + (mapDims.mapy >> 1));
const int xmax = std::min(xmin + SQUARE_SIZE, mapDims.mapx ), zmax = std::min(zmin + SQUARE_SIZE, mapDims.mapy );

for (int z = zmin; z < zmax; z++) {
for (int z = zmin; z < zmax; ) {
unsigned int zspan = zsize;

for (int x = xmin; x < xmax; ) {
n = nodeGrid[z * xsize + x];
x = n->xmax();

zspan = std::min(zspan, n->zmax() - z);
zspan = std::max(zspan, 1u);

n->SetMagicNumber(currMagicNum);
n->GetNeighbors(nodeGrid);
}

z += zspan;
}
}
{
// bottom-left quadrant: [0, mapDims.mapx >> 1) x [mapDims.mapy >> 1, mapDims.mapy)
const int xmin = (xoff + 0 ), zmin = (zoff + (mapDims.mapy >> 1));
const int xmax = std::min(xmin + SQUARE_SIZE, mapDims.mapx >> 1), zmax = std::min(zmin + SQUARE_SIZE, mapDims.mapy );

for (int z = zmin; z < zmax; z++) {
for (int z = zmin; z < zmax; ) {
unsigned int zspan = zsize;

for (int x = xmin; x < xmax; ) {
n = nodeGrid[z * xsize + x];
x = n->xmax();

zspan = std::min(zspan, n->zmax() - z);
zspan = std::max(zspan, 1u);

n->SetMagicNumber(currMagicNum);
n->GetNeighbors(nodeGrid);
}

z += zspan;
}
}
}
Expand All @@ -324,17 +352,25 @@ void QTPFS::NodeLayer::ExecNodeNeighborCacheUpdates(const SRectangle& ur, unsign

INode* n = NULL;

for (int z = zmin; z < zmax; z++) {
for (int z = zmin; z < zmax; ) {
unsigned int zspan = zsize;

for (int x = xmin; x < xmax; ) {
n = nodeGrid[z * xsize + x];
x = n->xmax();

// calculate largest safe z-increment along this row
zspan = std::min(zspan, n->zmax() - z);
zspan = std::max(zspan, 1u);

// NOTE:
// during initialization, currMagicNum == 0 which nodes start with already
// (does not matter because prevMagicNum == -1, so updates are not no-ops)
n->SetMagicNumber(currMagicNum);
n->UpdateNeighborCache(nodeGrid);
}

z += zspan;
}
}

Expand Down
22 changes: 11 additions & 11 deletions rts/System/Sound/ISound.cpp
Expand Up @@ -43,11 +43,11 @@ ISound::ISound()
{
}

void ISound::Initialize()
void ISound::Initialize(bool forceNullSound)
{
if (singleton == NULL) {
#ifndef NO_SOUND
if (!IsNullAudio()) {
if (!IsNullAudio() && !forceNullSound) {
Channels::BGMusic = new AudioChannel();
Channels::General = new AudioChannel();
Channels::Battle = new AudioChannel();
Expand All @@ -59,6 +59,11 @@ void ISound::Initialize()
// for it to finish (otherwise LoadSoundDefs can fail)
while (!singleton->CanLoadSoundDefs()) {
spring_sleep(spring_msecs(100));

if (singleton->SoundThreadQuit()) {
// no device or context found, fallback
ChangeOutput(true); break;
}
}
} else
#endif // NO_SOUND
Expand Down Expand Up @@ -93,27 +98,22 @@ void ISound::Shutdown()
}


bool ISound::IsInitialized()
{
return (singleton != NULL);
}

bool ISound::IsNullAudio()
{
return !configHandler->GetBool("Sound");
}


bool ISound::ChangeOutput()
bool ISound::ChangeOutput(bool forceNullSound)
{
if (IsNullAudio()) {
//FIXME: on reload, sound-ids change (depends on order when they are requested, see GetSoundId()/GetSoundItem()
LOG_L(L_ERROR, "re-enabling sound isn't supported yet, expect problems!");
}
Shutdown();
configHandler->Set("Sound", IsNullAudio());
Initialize();
return IsNullAudio();
configHandler->Set("Sound", IsNullAudio() || forceNullSound);
Initialize(forceNullSound);
return (IsNullAudio() || forceNullSound);
}

bool ISound::LoadSoundDefs(const std::string& filename)
Expand Down
8 changes: 5 additions & 3 deletions rts/System/Sound/ISound.h
Expand Up @@ -21,9 +21,9 @@ class ISound {
ISound();
virtual ~ISound() {};

static void Initialize();
static void Initialize(bool forceNullSound = false);
static void Shutdown();
static bool IsInitialized();
static bool IsInitialized() { return (singleton != NULL); }
static inline ISound* GetInstance() {
return singleton;
}
Expand All @@ -49,13 +49,15 @@ class ISound {
virtual bool IsMuted() const = 0;

///change current output device
static bool ChangeOutput();
static bool ChangeOutput(bool forceNullSound = false);

virtual void Iconified(bool state) = 0;

virtual void PrintDebugInfo() = 0;

virtual bool SoundThreadQuit() const = 0;
virtual bool CanLoadSoundDefs() const = 0;

bool LoadSoundDefs(const std::string& fileName);

virtual const float3& GetListenerPos() const = 0;
Expand Down
1 change: 1 addition & 0 deletions rts/System/Sound/Null/NullSound.h
Expand Up @@ -36,6 +36,7 @@ class NullSound : public ISound
void Iconified(bool state) {}

void PrintDebugInfo();
bool SoundThreadQuit() const { return false; }
bool CanLoadSoundDefs() const { return true; }
bool LoadSoundDefsImpl(const std::string& fileName) { return false; }

Expand Down
51 changes: 23 additions & 28 deletions rts/System/Sound/OpenAL/Sound.cpp
Expand Up @@ -101,19 +101,10 @@ CSound::~CSound()

bool CSound::HasSoundItem(const std::string& name) const
{
soundMapT::const_iterator it = soundMap.find(name);
if (it != soundMap.end())
{
if (soundMap.find(name) != soundMap.end())
return true;
}
else
{
soundItemDefMap::const_iterator it = soundItemDefs.find(StringToLower(name));
if (it != soundItemDefs.end())
return true;
else
return false;
}

return (soundItemDefs.find(StringToLower(name)) != soundItemDefs.end());
}

size_t CSound::GetSoundId(const std::string& name)
Expand All @@ -127,22 +118,22 @@ size_t CSound::GetSoundId(const std::string& name)
if (it != soundMap.end()) {
// sounditem found
return it->second;
} else {
soundItemDefMap::const_iterator itemDefIt = soundItemDefs.find(StringToLower(name));
if (itemDefIt != soundItemDefs.end()) {
return MakeItemFromDef(itemDefIt->second);
} else {
if (LoadSoundBuffer(name) > 0) // maybe raw filename?
{
soundItemDef temp = defaultItem;
temp["file"] = name;
return MakeItemFromDef(temp);
} else {
LOG_L(L_ERROR, "CSound::GetSoundId: could not find sound: %s", name.c_str());
return 0;
}
}
}

soundItemDefMap::const_iterator itemDefIt = soundItemDefs.find(StringToLower(name));
if (itemDefIt != soundItemDefs.end()) {
return MakeItemFromDef(itemDefIt->second);
}

if (LoadSoundBuffer(name) > 0) {
// maybe raw filename?
soundItemDef temp = defaultItem;
temp["file"] = name;
return MakeItemFromDef(temp);
}

LOG_L(L_ERROR, "CSound::GetSoundId: could not find sound: %s", name.c_str());
return 0;
}

SoundItem* CSound::GetSoundItem(size_t id) const {
Expand Down Expand Up @@ -254,7 +245,7 @@ bool CSound::Mute()
boost::recursive_mutex::scoped_lock lck(soundMutex);
mute = !mute;
if (mute)
alListenerf(AL_GAIN, 0.0);
alListenerf(AL_GAIN, 0.0f);
else
alListenerf(AL_GAIN, masterVolume);
return mute;
Expand Down Expand Up @@ -313,6 +304,8 @@ void CSound::StartThread(int maxSounds)
if (device == NULL) {
LOG_L(L_ERROR, "Could not open a sound device, disabling sounds");
CheckError("CSound::InitAL");
// fall back to NullSound
soundThreadQuit = true;
return;
} else {
ALCcontext* context = alcCreateContext(device, NULL);
Expand All @@ -323,6 +316,8 @@ void CSound::StartThread(int maxSounds)
} else {
alcCloseDevice(device);
LOG_L(L_ERROR, "Could not create OpenAL audio context");
// fall back to NullSound
soundThreadQuit = true;
return;
}
}
Expand Down
2 changes: 2 additions & 0 deletions rts/System/Sound/OpenAL/Sound.h
Expand Up @@ -54,7 +54,9 @@ class CSound : public ISound

virtual void PrintDebugInfo();

bool SoundThreadQuit() const { return soundThreadQuit; }
bool CanLoadSoundDefs() const { return canLoadDefs; }

bool LoadSoundDefsImpl(const std::string& fileName);
const float3& GetListenerPos() const { return myPos; }

Expand Down

0 comments on commit a8ba4cc

Please sign in to comment.