summaryrefslogtreecommitdiff
path: root/indra/llcommon/llsingleton.cpp
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2021-05-10 15:21:51 -0400
committerNat Goodspeed <nat@lindenlab.com>2021-05-10 15:21:51 -0400
commit95d8085fa42ca73773a06f2bd5622f69aef0e598 (patch)
tree2d8d6543ce378ed4c7bdbc007042b6148653e0d7 /indra/llcommon/llsingleton.cpp
parentce65bc2f13409d75dbc6502c970030cc5ed2e5ad (diff)
SL-10297: Make LLSingletonBase::llerrs() et al. runtime variadic.
Instead of accepting a fixed list of (const char* p1="", etc.), accept (std::initializer_list<std::string_view>). Accepting a std::initializer_list<T> in your parameter list allows coding (e.g.) func({T0, T1, T2, ... }); -- in other words, you can pass the initializer_list a brace-enclosed list of an arbitrary number of instances of T. Using std::string_view instead of const char* means we can pass *either* const char* or std::string. string_view is cheaply constructed from either, allowing uniform treatment within the function. Constructing string_view from std::string simply extracts the pointer and length from the std::string. Constructing string_view from const char* (e.g. a "string literal") requires scanning the string for its terminating nul byte -- but that would be necessary even if the scan were deferred until the function body. Since string_view stores the length, the scan still happens only once.
Diffstat (limited to 'indra/llcommon/llsingleton.cpp')
-rw-r--r--indra/llcommon/llsingleton.cpp66
1 files changed, 36 insertions, 30 deletions
diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp
index ad933154c2..d0dcd463ff 100644
--- a/indra/llcommon/llsingleton.cpp
+++ b/indra/llcommon/llsingleton.cpp
@@ -39,8 +39,7 @@
#include <stdexcept>
namespace {
-void log(LLError::ELevel level,
- const char* p1, const char* p2, const char* p3, const char* p4);
+void log(LLError::ELevel level, std::initializer_list<std::string_view>);
} // anonymous namespace
// Our master list of all LLSingletons is itself an LLSingleton. We used to
@@ -218,8 +217,8 @@ void LLSingletonBase::pop_initializing()
if (list.empty())
{
- logerrs("Underflow in stack of currently-initializing LLSingletons at ",
- classname(this).c_str(), "::getInstance()");
+ logerrs({"Underflow in stack of currently-initializing LLSingletons at ",
+ classname(this), "::getInstance()"});
}
// Now we know list.back() exists: capture it
@@ -240,9 +239,9 @@ void LLSingletonBase::pop_initializing()
// Now validate the newly-popped LLSingleton.
if (back != this)
{
- logerrs("Push/pop mismatch in stack of currently-initializing LLSingletons: ",
- classname(this).c_str(), "::getInstance() trying to pop ",
- classname(back).c_str());
+ logerrs({"Push/pop mismatch in stack of currently-initializing LLSingletons: ",
+ classname(this), "::getInstance() trying to pop ",
+ classname(back)});
}
// log AFTER popping so logging singletons don't cry circularity
@@ -331,15 +330,15 @@ void LLSingletonBase::capture_dependency()
//
// Example: LLNotifications singleton initializes default channels.
// Channels register themselves with singleton once done.
- logdebugs("LLSingleton circularity: ", out.str().c_str(),
- classname(this).c_str(), "");
+ logdebugs({"LLSingleton circularity: ", out.str(),
+ classname(this)});
}
else
{
// Actual circularity with other singleton (or single singleton is used extensively).
// Dependency can be unclear.
- logwarns("LLSingleton circularity: ", out.str().c_str(),
- classname(this).c_str(), "");
+ logwarns({"LLSingleton circularity: ", out.str(),
+ classname(this)});
}
}
else
@@ -352,8 +351,8 @@ void LLSingletonBase::capture_dependency()
if (current->mDepends.insert(this).second)
{
// only log the FIRST time we hit this dependency!
- logdebugs(classname(current).c_str(),
- " depends on ", classname(this).c_str());
+ logdebugs({classname(current),
+ " depends on ", classname(this)});
}
}
}
@@ -401,7 +400,7 @@ LLSingletonBase::vec_t LLSingletonBase::dep_sort()
void LLSingletonBase::cleanup_()
{
- logdebugs("calling ", classname(this).c_str(), "::cleanupSingleton()");
+ logdebugs({"calling ", classname(this), "::cleanupSingleton()"});
try
{
cleanupSingleton();
@@ -427,23 +426,23 @@ void LLSingletonBase::deleteAll()
if (! sp->mDeleteSingleton)
{
// This Should Not Happen... but carry on.
- logwarns(name.c_str(), "::mDeleteSingleton not initialized!");
+ logwarns({name, "::mDeleteSingleton not initialized!"});
}
else
{
// properly initialized: call it.
- logdebugs("calling ", name.c_str(), "::deleteSingleton()");
+ logdebugs({"calling ", name, "::deleteSingleton()"});
// From this point on, DO NOT DEREFERENCE sp!
sp->mDeleteSingleton();
}
}
catch (const std::exception& e)
{
- logwarns("Exception in ", name.c_str(), "::deleteSingleton(): ", e.what());
+ logwarns({"Exception in ", name, "::deleteSingleton(): ", e.what()});
}
catch (...)
{
- logwarns("Unknown exception in ", name.c_str(), "::deleteSingleton()");
+ logwarns({"Unknown exception in ", name, "::deleteSingleton()"});
}
}
}
@@ -451,40 +450,47 @@ void LLSingletonBase::deleteAll()
/*---------------------------- Logging helpers -----------------------------*/
namespace {
-void log(LLError::ELevel level,
- const char* p1, const char* p2, const char* p3, const char* p4)
+void log(LLError::ELevel level, std::initializer_list<std::string_view> args)
{
- LL_VLOGS(level, "LLSingleton") << p1 << p2 << p3 << p4 << LL_ENDL;
+ LL_VLOGS(level, "LLSingleton");
+ for (auto arg : args)
+ {
+ LL_CONT << arg;
+ }
+ LL_ENDL;
}
} // anonymous namespace
//static
-void LLSingletonBase::logwarns(const char* p1, const char* p2, const char* p3, const char* p4)
+void LLSingletonBase::logwarns(std::initializer_list<std::string_view> args)
{
- log(LLError::LEVEL_WARN, p1, p2, p3, p4);
+ log(LLError::LEVEL_WARN, args);
}
//static
-void LLSingletonBase::loginfos(const char* p1, const char* p2, const char* p3, const char* p4)
+void LLSingletonBase::loginfos(std::initializer_list<std::string_view> args)
{
- log(LLError::LEVEL_INFO, p1, p2, p3, p4);
+ log(LLError::LEVEL_INFO, args);
}
//static
-void LLSingletonBase::logdebugs(const char* p1, const char* p2, const char* p3, const char* p4)
+void LLSingletonBase::logdebugs(std::initializer_list<std::string_view> args)
{
- log(LLError::LEVEL_DEBUG, p1, p2, p3, p4);
+ log(LLError::LEVEL_DEBUG, args);
}
//static
-void LLSingletonBase::logerrs(const char* p1, const char* p2, const char* p3, const char* p4)
+void LLSingletonBase::logerrs(std::initializer_list<std::string_view> args)
{
- log(LLError::LEVEL_ERROR, p1, p2, p3, p4);
+ log(LLError::LEVEL_ERROR, args);
// The other important side effect of LL_ERRS() is
// https://www.youtube.com/watch?v=OMG7paGJqhQ (emphasis on OMG)
std::ostringstream out;
- out << p1 << p2 << p3 << p4;
+ for (auto arg : args)
+ {
+ out << arg;
+ }
auto crash = LLError::getFatalFunction();
if (crash)
{