Proper way to clear all sounds?
What is the proper way to clear out the sound manager when calling SceneManager::clearScene? It often crashes if there are active sounds and I call clearScene. I haven't been able to pin down the exact issue, but it seems like maybe its not waiting for the thread to finish its queue to destroy each sound properly.
Is there a way to wait for the queue to empty before moving on? Such as a soundManager->waitForQueueEmpty() or something? Or is this the wrong approach?
Ideally you should use OgreOggSoundManager::destroyAllSounds().
Could you upload a test app and I'll take a look?
Just an update,
I tried a quick test in debug and release with a couple of sounds and didn't experience any issues, so if you can provide an app demonstrating the problem or you manage to pinpoint the issue let me know
I'm looking at my stack and it appears that my main thread is cleaning up all the moveable objects:
> OgreOggSound_d.dll!OgreOggSound::OgreOggSoundManager::_releaseSoundImpl(OgreOggSound::OgreOggISound * sound=0x13889020) Line 2181 + 0x16 bytes C++
OgreOggSound_d.dll!OgreOggSound::OgreOggSoundFactory::destroyInstance(Ogre::MovableObject * obj=0x13889020) Line 112 C++
OgreMain_d.dll!Ogre::SceneManager::destroyAllMovableObjects() Line 6576 + 0x1b bytes C++
OgreMain_d.dll!Ogre::SceneManager::clearScene() Line 765 + 0x12 bytes C++
Meanwhile, the sound thread is also trying to destroy these moveable objects:
OgreMain_d.dll!Ogre::SceneManager::destroyMovableObject(Ogre::MovableObject * m=0x1297d510) Line 6640 + 0xa bytes C++
OgreOggSound_d.dll!OgreOggSound::OgreOggSoundManager::_destroySoundImpl(OgreOggSound::OgreOggISound * sound=0x1297d510) Line 2194 + 0x16 bytes C++
> OgreOggSound_d.dll!OgreOggSound::OgreOggSoundManager::_processQueuedSounds() Line 2646 + 0x12 bytes C++
OgreOggSound_d.dll!OgreOggSound::OgreOggSoundManager::threadUpdate() Line 688 C++
During my test I had many sounds playing, around 64. And then I run my clean up routine which calls destroySound on each sound, then calls destroyAllSounds, just in case. And then immediately follows it with SceneManager::clearScene. Could the background thread be trying to destroy something at the same time as the main thread?
You should be able to just call clearScene() which will destroy all sounds automatically.
destroyMovableObject() should internally call my overridden destroy function for the movableObject where I handle thread locking issues myself.
What your doing presently is queueing up a list of destroy calls inside the soundmanager then simultaneously calling destroy on the same objects via OGRE, I haven't thought of a suitable solution to this problem yet, as there's not really a method for intercommunication between OGRE and external threads for this kind of thing.
Hopefully letting OGRE cleanup via clearScene() should work fine, if not let me know as that would indicate a bug somewhere. For now though, consideration needs to be taken when handling total destruction/creation scenarios in-game.
The alternative to all this is to use the non-threaded version of the library which should suffer none of these issues...
Depends if you need the background streaming support in your application?
I've made an ammendment to destroyAllSounds() to use a mutex lock to prevent the thread issues you've been having.
Could you try the latest SVN with your original code to see if it clears up the crashing?
I will be out of the country for a couple weeks, but I will test it as soon as I get back.
Further to this, I've identified a bug in destroyAllSounds() which should now be fixed, get the latest SVN and let me know.