summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorBrad Payne (Vir Linden) <vir@lindenlab.com>2020-11-13 13:59:36 +0000
committerBrad Payne (Vir Linden) <vir@lindenlab.com>2020-11-13 13:59:36 +0000
commite3de5de3c1374de3829e21d67bc93cfcf9eea848 (patch)
tree8236679e2324f02bd0e2f204ea93fce5baef1e45 /indra/llcommon
parentc79e648aac9bb32cc1d49d39973b5e96f25828f0 (diff)
parent04c473ab46041133ea6a87dbe0d43e662472adf5 (diff)
Merge remote-tracking branch 'origin/master' into DRTVWR-517
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/llapp.cpp2
-rw-r--r--indra/llcommon/llapr.cpp2
-rw-r--r--indra/llcommon/llcleanup.cpp7
-rw-r--r--indra/llcommon/llcleanup.h13
-rw-r--r--indra/llcommon/llcommon.cpp2
-rw-r--r--indra/llcommon/llerror.cpp84
-rw-r--r--indra/llcommon/llerrorcontrol.h5
-rw-r--r--indra/llcommon/llsingleton.cpp31
8 files changed, 59 insertions, 87 deletions
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 3dab632aef..a90b294550 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -180,7 +180,7 @@ LLApp::~LLApp()
if(mExceptionHandler != 0) delete mExceptionHandler;
- SUBSYSTEM_CLEANUP(LLCommon);
+ SUBSYSTEM_CLEANUP_DBG(LLCommon);
}
// static
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index 984e90f376..db94765871 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -68,7 +68,7 @@ void ll_cleanup_apr()
{
gAPRInitialized = false;
- LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL;
+ LL_DEBUGS("APR") << "Cleaning up APR" << LL_ENDL;
LLThreadLocalPointerBase::destroyAllThreadLocalStorage();
diff --git a/indra/llcommon/llcleanup.cpp b/indra/llcommon/llcleanup.cpp
index c5283507bf..1f34c2036a 100644
--- a/indra/llcommon/llcleanup.cpp
+++ b/indra/llcommon/llcleanup.cpp
@@ -20,10 +20,13 @@
#include "llerror.h"
#include "llerrorcontrol.h"
-void log_subsystem_cleanup(const char* file, int line, const char* function,
+void log_subsystem_cleanup(LLError::ELevel level,
+ const char* file,
+ int line,
+ const char* function,
const char* classname)
{
- LL_INFOS("Cleanup") << LLError::abbreviateFile(file) << "(" << line << "): "
+ LL_VLOGS(level, "Cleanup") << LLError::abbreviateFile(file) << "(" << line << "): "
<< "calling " << classname << "::cleanupClass() in "
<< function << LL_ENDL;
}
diff --git a/indra/llcommon/llcleanup.h b/indra/llcommon/llcleanup.h
index a319171b5f..0f567ed5f6 100644
--- a/indra/llcommon/llcleanup.h
+++ b/indra/llcommon/llcleanup.h
@@ -21,13 +21,22 @@
// shutdown schemes.
#define SUBSYSTEM_CLEANUP(CLASSNAME) \
do { \
- log_subsystem_cleanup(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, #CLASSNAME); \
+ log_subsystem_cleanup(LLError::LEVEL_INFO, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, #CLASSNAME); \
+ CLASSNAME::cleanupClass(); \
+ } while (0)
+
+#define SUBSYSTEM_CLEANUP_DBG(CLASSNAME) \
+ do { \
+ log_subsystem_cleanup(LLError::LEVEL_DEBUG, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, #CLASSNAME); \
CLASSNAME::cleanupClass(); \
} while (0)
// Use ancient do { ... } while (0) macro trick to permit a block of
// statements with the same syntax as a single statement.
-void log_subsystem_cleanup(const char* file, int line, const char* function,
+void log_subsystem_cleanup(LLError::ELevel level,
+ const char* file,
+ int line,
+ const char* function,
const char* classname);
#endif /* ! defined(LL_LLCLEANUP_H) */
diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp
index 2d665c611b..96be913d17 100644
--- a/indra/llcommon/llcommon.cpp
+++ b/indra/llcommon/llcommon.cpp
@@ -63,7 +63,7 @@ void LLCommon::cleanupClass()
sMasterThreadRecorder = NULL;
LLTrace::set_master_thread_recorder(NULL);
LLThreadSafeRefCount::cleanupThreadSafeRefCount();
- SUBSYSTEM_CLEANUP(LLTimer);
+ SUBSYSTEM_CLEANUP_DBG(LLTimer);
if (sAprInitialized)
{
ll_cleanup_apr();
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 411412c883..f876b8ee4a 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -332,12 +332,9 @@ namespace LLError
}
// huh, that's odd, we should see one or the other prefix -- but don't
// try to log unless logging is already initialized
- if (is_available())
- {
- // in Python, " or ".join(vector) -- but in C++, a PITB
- LL_DEBUGS() << "Did not see 'class' or 'struct' prefix on '"
- << name << "'" << LL_ENDL;
- }
+ // in Python, " or ".join(vector) -- but in C++, a PITB
+ LL_DEBUGS() << "Did not see 'class' or 'struct' prefix on '"
+ << name << "'" << LL_ENDL;
return name;
#else // neither GCC nor Visual Studio
@@ -438,9 +435,12 @@ namespace
typedef std::vector<LLError::RecorderPtr> Recorders;
typedef std::vector<LLError::CallSite*> CallSiteVector;
- class Globals : public LLSingleton<Globals>
+ class Globals
{
- LLSINGLETON(Globals);
+ public:
+ static Globals* getInstance();
+ protected:
+ Globals();
public:
std::ostringstream messageStream;
bool messageStreamInUse;
@@ -460,6 +460,16 @@ namespace
{
}
+ Globals* Globals::getInstance()
+ {
+ // According to C++11 Function-Local Initialization
+ // of static variables is supposed to be thread safe
+ // without risk of deadlocks.
+ static Globals inst;
+
+ return &inst;
+ }
+
void Globals::addCallSite(LLError::CallSite& site)
{
callSites.push_back(&site);
@@ -512,14 +522,17 @@ namespace LLError
typedef LLPointer<SettingsConfig> SettingsConfigPtr;
- class Settings : public LLSingleton<Settings>
+ class Settings
{
- LLSINGLETON(Settings);
+ public:
+ static Settings* getInstance();
+ protected:
+ Settings();
public:
SettingsConfigPtr getSettingsConfig();
void reset();
- SettingsStoragePtr saveAndReset();
+ SettingsStoragePtr saveAndReset();
void restore(SettingsStoragePtr pSettingsStorage);
private:
@@ -553,6 +566,16 @@ namespace LLError
{
}
+ Settings* Settings::getInstance()
+ {
+ // According to C++11 Function-Local Initialization
+ // of static variables is supposed to be thread safe
+ // without risk of deadlocks.
+ static Settings inst;
+
+ return &inst;
+ }
+
SettingsConfigPtr Settings::getSettingsConfig()
{
return mSettingsConfig;
@@ -577,11 +600,6 @@ namespace LLError
SettingsConfigPtr newSettingsConfig(dynamic_cast<SettingsConfig *>(pSettingsStorage.get()));
mSettingsConfig = newSettingsConfig;
}
-
- bool is_available()
- {
- return Settings::instanceExists() && Globals::instanceExists();
- }
}
namespace LLError
@@ -1028,7 +1046,7 @@ namespace LLError
std::pair<boost::shared_ptr<RECORDER>, Recorders::iterator>
findRecorderPos()
{
- SettingsConfigPtr s = Settings::instance().getSettingsConfig();
+ SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
// Since we promise to return an iterator, use a classic iterator
// loop.
auto end{s->mRecorders.end()};
@@ -1071,7 +1089,7 @@ namespace LLError
auto found = findRecorderPos<RECORDER>();
if (found.first)
{
- SettingsConfigPtr s = Settings::instance().getSettingsConfig();
+ SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
s->mRecorders.erase(found.second);
}
return bool(found.first);
@@ -1307,14 +1325,6 @@ 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++;
@@ -1353,10 +1363,8 @@ namespace LLError
std::ostringstream* Log::out()
{
LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5);
- // 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.isLocked() && ! (Settings::wasDeleted() || Globals::wasDeleted()))
+
+ if (lock.isLocked())
{
Globals* g = Globals::getInstance();
@@ -1378,14 +1386,6 @@ 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;
- }
-
if(strlen(out->str().c_str()) < 128)
{
strcpy(message, out->str().c_str());
@@ -1418,14 +1418,6 @@ 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/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h
index bfa2269025..25786d5457 100644
--- a/indra/llcommon/llerrorcontrol.h
+++ b/indra/llcommon/llerrorcontrol.h
@@ -203,11 +203,6 @@ namespace LLError
LL_COMMON_API std::string abbreviateFile(const std::string& filePath);
LL_COMMON_API int shouldLogCallCount();
-
- // Check whether Globals exists. This should only be used by LLSingleton
- // infrastructure to avoid trying to log when our internal LLSingleton is
- // unavailable -- circularity ensues.
- LL_COMMON_API bool is_available();
};
#endif // LL_LLERRORCONTROL_H
diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp
index d3d25201b2..83a4b64e8f 100644
--- a/indra/llcommon/llsingleton.cpp
+++ b/indra/llcommon/llsingleton.cpp
@@ -28,7 +28,7 @@
#include "llsingleton.h"
#include "llerror.h"
-#include "llerrorcontrol.h" // LLError::is_available()
+#include "llerrorcontrol.h"
#include "lldependencies.h"
#include "llexception.h"
#include "llcoros.h"
@@ -41,8 +41,6 @@
namespace {
void log(LLError::ELevel level,
const char* p1, const char* p2, const char* p3, const char* p4);
-
-bool oktolog();
} // anonymous namespace
// Our master list of all LLSingletons is itself an LLSingleton. We used to
@@ -279,8 +277,6 @@ void LLSingletonBase::reset_initializing(list_t::size_type size)
void LLSingletonBase::MasterList::LockedInitializing::log(const char* verb, const char* name)
{
- if (oktolog())
- {
LL_DEBUGS("LLSingleton") << verb << ' ' << demangle(name) << ';';
if (mList)
{
@@ -292,7 +288,6 @@ void LLSingletonBase::MasterList::LockedInitializing::log(const char* verb, cons
}
}
LL_ENDL;
- }
}
void LLSingletonBase::capture_dependency()
@@ -455,33 +450,11 @@ void LLSingletonBase::deleteAll()
/*---------------------------- Logging helpers -----------------------------*/
namespace {
-bool oktolog()
-{
- // See comments in log() below.
- return LLError::is_available();
-}
void log(LLError::ELevel level,
const char* p1, const char* p2, const char* p3, const char* p4)
{
- // The is_available() test below ensures that we'll stop logging once
- // LLError has been cleaned up. If we had a similar portable test for
- // std::cerr, this would be a good place to use it.
-
- // Check LLError::is_available() because some of LLError's infrastructure
- // is itself an LLSingleton. If that LLSingleton has not yet been
- // initialized, trying to log will engage LLSingleton machinery... and
- // around and around we go.
- if (LLError::is_available())
- {
- LL_VLOGS(level, "LLSingleton") << p1 << p2 << p3 << p4 << LL_ENDL;
- }
- else
- {
- // Caller may be a test program, or something else whose stderr is
- // visible to the user.
- std::cerr << p1 << p2 << p3 << p4 << std::endl;
- }
+ LL_VLOGS(level, "LLSingleton") << p1 << p2 << p3 << p4 << LL_ENDL;
}
} // anonymous namespace