From 1a8c8df6862620de64f621363b025b0ffbef72fa Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 13 Mar 2017 14:09:14 -0400 Subject: DRTVWR-418: Ignore logging that requires resurrecting singletons. The logging subsystem depends on two different LLSingletons for some reason. It turns out to be very difficult to completely avoid executing any logging calls after the LLSingletonBase::deleteAll(), but we really don't want to resurrect those LLSingletons so late in the run for a couple stragglers. Introduce LLSingleton::wasDeleted() query method, and use it in logging subsystem to simply bypass last-millisecond logging requests. --- indra/llcommon/llerror.cpp | 97 ++++++++++++++++++++++++++++---------------- indra/llcommon/llsingleton.h | 8 ++++ 2 files changed, 70 insertions(+), 35 deletions(-) diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index e6407ecf22..2ddb3edbdd 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -1067,7 +1067,15 @@ namespace LLError { return false; } - + + // If we hit a logging request very late during shutdown processing, + // when either of the relevant LLSingletons has already been deleted, + // DO NOT resurrect them. + if (Settings::wasDeleted() || Globals::wasDeleted()) + { + return false; + } + SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); s->mShouldLogCallCounter++; @@ -1106,7 +1114,10 @@ namespace LLError std::ostringstream* Log::out() { LogLock lock; - if (lock.ok()) + // If we hit a logging request very late during shutdown processing, + // when either of the relevant LLSingletons has already been deleted, + // DO NOT resurrect them. + if (lock.ok() && ! (Settings::wasDeleted() || Globals::wasDeleted())) { Globals* g = Globals::getInstance(); @@ -1116,41 +1127,49 @@ namespace LLError return &g->messageStream; } } - + return new std::ostringstream; } - + void Log::flush(std::ostringstream* out, char* message) - { - LogLock lock; - if (!lock.ok()) - { - return; - } - - if(strlen(out->str().c_str()) < 128) - { - strcpy(message, out->str().c_str()); - } - else - { - strncpy(message, out->str().c_str(), 127); - message[127] = '\0' ; - } - - Globals* g = Globals::getInstance(); - if (out == &g->messageStream) - { - g->messageStream.clear(); - g->messageStream.str(""); - g->messageStreamInUse = false; - } - else - { - delete out; - } - return ; - } + { + LogLock lock; + if (!lock.ok()) + { + return; + } + + // If we hit a logging request very late during shutdown processing, + // when either of the relevant LLSingletons has already been deleted, + // DO NOT resurrect them. + if (Settings::wasDeleted() || Globals::wasDeleted()) + { + return; + } + + if(strlen(out->str().c_str()) < 128) + { + strcpy(message, out->str().c_str()); + } + else + { + strncpy(message, out->str().c_str(), 127); + message[127] = '\0' ; + } + + Globals* g = Globals::getInstance(); + if (out == &g->messageStream) + { + g->messageStream.clear(); + g->messageStream.str(""); + g->messageStreamInUse = false; + } + else + { + delete out; + } + return ; + } void Log::flush(std::ostringstream* out, const CallSite& site) { @@ -1159,7 +1178,15 @@ namespace LLError { return; } - + + // If we hit a logging request very late during shutdown processing, + // when either of the relevant LLSingletons has already been deleted, + // DO NOT resurrect them. + if (Settings::wasDeleted() || Globals::wasDeleted()) + { + return; + } + Globals* g = Globals::getInstance(); SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 1b915dfd6e..0d4a1f34f8 100644 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -452,6 +452,14 @@ public: return sData.mInitState == INITIALIZED; } + // Has this singleton been deleted? This can be useful during shutdown + // processing to avoid "resurrecting" a singleton we thought we'd already + // cleaned up. + static bool wasDeleted() + { + return sData.mInitState == DELETED; + } + private: struct SingletonData { -- cgit v1.2.3