summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2021-11-01 23:30:55 +0200
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2021-11-18 20:37:26 +0200
commite729910e1b7ac1ea9961049e7fe96194cbc7f805 (patch)
tree8db30f645c26b159db5b43c436f506d237289fd4 /indra
parentac2135a459f65cf9fdeb7715bcc5b4a6f1c47990 (diff)
SL-14992 fmod shutdown crash
Diffstat (limited to 'indra')
-rw-r--r--indra/llaudio/llstreamingaudio_fmodstudio.cpp73
-rw-r--r--indra/llaudio/llstreamingaudio_fmodstudio.h2
2 files changed, 59 insertions, 16 deletions
diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.cpp b/indra/llaudio/llstreamingaudio_fmodstudio.cpp
index 6439095cee..1ad29a3f59 100644
--- a/indra/llaudio/llstreamingaudio_fmodstudio.cpp
+++ b/indra/llaudio/llstreamingaudio_fmodstudio.cpp
@@ -84,9 +84,64 @@ mRetryCount(0)
LLStreamingAudio_FMODSTUDIO::~LLStreamingAudio_FMODSTUDIO()
{
- // nothing interesting/safe to do.
+ if (mCurrentInternetStreamp)
+ {
+ // Isn't supposed to hapen, stream should be clear by now,
+ // and if it does, we are likely going to crash.
+ LL_WARNS("FMOD") << "mCurrentInternetStreamp not null on shutdown!" << LL_ENDL;
+ stop();
+ }
+
+ // Kill dead internet streams, if possible
+ killDeadStreams();
+
+ if (!mDeadStreams.empty())
+ {
+ // LLStreamingAudio_FMODSTUDIO was inited on startup
+ // and should be destroyed on shutdown, it should
+ // wait for streams to die to not cause crashes or
+ // leaks.
+ // Ideally we need to wait on some kind of callback
+ // to release() streams correctly, but 200 ms should
+ // be enough and we can't wait forever.
+ LL_INFOS("FMOD") << "Waiting for " << (S32)mDeadStreams.size() << " streams to stop" << LL_ENDL;
+ for (S32 i = 0; i < 20; i++)
+ {
+ const U32 ms_delay = 10;
+ ms_sleep(ms_delay); // rude, but not many options here
+ killDeadStreams();
+ if (mDeadStreams.empty())
+ {
+ LL_INFOS("FMOD") << "All streams stopped after " << (S32)((i + 1) * ms_delay) << "ms" << LL_ENDL;
+ break;
+ }
+ }
+ }
+
+ if (!mDeadStreams.empty())
+ {
+ LL_WARNS("FMOD") << "Failed to kill some audio streams" << LL_ENDL;
+ }
}
+void LLStreamingAudio_FMODSTUDIO::killDeadStreams()
+{
+ std::list<LLAudioStreamManagerFMODSTUDIO *>::iterator iter;
+ for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();)
+ {
+ LLAudioStreamManagerFMODSTUDIO *streamp = *iter;
+ if (streamp->stopStream())
+ {
+ LL_INFOS("FMOD") << "Closed dead stream" << LL_ENDL;
+ delete streamp;
+ mDeadStreams.erase(iter++);
+ }
+ else
+ {
+ iter++;
+ }
+ }
+}
void LLStreamingAudio_FMODSTUDIO::start(const std::string& url)
{
@@ -118,21 +173,7 @@ void LLStreamingAudio_FMODSTUDIO::start(const std::string& url)
void LLStreamingAudio_FMODSTUDIO::update()
{
// Kill dead internet streams, if possible
- std::list<LLAudioStreamManagerFMODSTUDIO *>::iterator iter;
- for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();)
- {
- LLAudioStreamManagerFMODSTUDIO *streamp = *iter;
- if (streamp->stopStream())
- {
- LL_INFOS("FMOD") << "Closed dead stream" << LL_ENDL;
- delete streamp;
- mDeadStreams.erase(iter++);
- }
- else
- {
- iter++;
- }
- }
+ killDeadStreams();
// Don't do anything if there are no streams playing
if (!mCurrentInternetStreamp)
diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.h b/indra/llaudio/llstreamingaudio_fmodstudio.h
index ea451bc9b5..35a7b1226e 100644
--- a/indra/llaudio/llstreamingaudio_fmodstudio.h
+++ b/indra/llaudio/llstreamingaudio_fmodstudio.h
@@ -59,6 +59,8 @@ public:
/*virtual*/ bool supportsAdjustableBufferSizes(){return true;}
/*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime);
private:
+ void killDeadStreams();
+
FMOD::System *mSystem;
LLAudioStreamManagerFMODSTUDIO *mCurrentInternetStreamp;