summaryrefslogtreecommitdiff
path: root/indra/llcommon/llsingleton.h
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.h
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.h')
-rw-r--r--indra/llcommon/llsingleton.h81
1 files changed, 39 insertions, 42 deletions
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 30a5b21cf8..b9570d42db 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -34,6 +34,7 @@
#include "lockstatic.h"
#include "llthread.h" // on_main_thread()
#include "llmainthreadtask.h"
+#include <initializer_list>
class LLSingletonBase: private boost::noncopyable
{
@@ -111,14 +112,10 @@ protected:
void capture_dependency();
// delegate logging calls to llsingleton.cpp
- static void logerrs(const char* p1, const char* p2="",
- const char* p3="", const char* p4="");
- static void logwarns(const char* p1, const char* p2="",
- const char* p3="", const char* p4="");
- static void loginfos(const char* p1, const char* p2="",
- const char* p3="", const char* p4="");
- static void logdebugs(const char* p1, const char* p2="",
- const char* p3="", const char* p4="");
+ static void logerrs (std::initializer_list<std::string_view>);
+ static void logwarns (std::initializer_list<std::string_view>);
+ static void loginfos (std::initializer_list<std::string_view>);
+ static void logdebugs(std::initializer_list<std::string_view>);
static std::string demangle(const char* mangled);
// these classname() declarations restate template functions declared in
// llerror.h because we avoid #including that here
@@ -327,8 +324,8 @@ private:
// init stack to its previous size BEFORE logging so log-machinery
// LLSingletons don't record a dependency on DERIVED_TYPE!
LLSingleton_manage_master<DERIVED_TYPE>().reset_initializing(prev_size);
- logwarns("Error constructing ", classname<DERIVED_TYPE>().c_str(),
- ": ", err.what());
+ logwarns({"Error constructing ", classname<DERIVED_TYPE>(),
+ ": ", err.what()});
// There isn't a separate EInitState value meaning "we attempted
// to construct this LLSingleton subclass but could not," so use
// DELETED. That seems slightly more appropriate than UNINITIALIZED.
@@ -356,8 +353,8 @@ private:
// BEFORE logging, so log-machinery LLSingletons don't record a
// dependency on DERIVED_TYPE!
pop_initializing(lk->mInstance);
- logwarns("Error in ", classname<DERIVED_TYPE>().c_str(),
- "::initSingleton(): ", err.what());
+ logwarns({"Error in ", classname<DERIVED_TYPE>(),
+ "::initSingleton(): ", err.what()});
// Get rid of the instance entirely. This call depends on our
// recursive_mutex. We could have a deleteSingleton(LockStatic&)
// overload and pass lk, but we don't strictly need it.
@@ -506,9 +503,9 @@ public:
case CONSTRUCTING:
// here if DERIVED_TYPE's constructor (directly or indirectly)
// calls DERIVED_TYPE::getInstance()
- logerrs("Tried to access singleton ",
- classname<DERIVED_TYPE>().c_str(),
- " from singleton constructor!");
+ logerrs({"Tried to access singleton ",
+ classname<DERIVED_TYPE>(),
+ " from singleton constructor!"});
return nullptr;
case INITIALIZING:
@@ -523,9 +520,9 @@ public:
case DELETED:
// called after deleteSingleton()
- logwarns("Trying to access deleted singleton ",
- classname<DERIVED_TYPE>().c_str(),
- " -- creating new instance");
+ logwarns({"Trying to access deleted singleton ",
+ classname<DERIVED_TYPE>(),
+ " -- creating new instance"});
// fall through
case UNINITIALIZED:
case QUEUED:
@@ -552,8 +549,8 @@ public:
} // unlock 'lk'
// Per the comment block above, dispatch to the main thread.
- loginfos(classname<DERIVED_TYPE>().c_str(),
- "::getInstance() dispatching to main thread");
+ loginfos({classname<DERIVED_TYPE>(),
+ "::getInstance() dispatching to main thread"});
auto instance = LLMainThreadTask::dispatch(
[](){
// VERY IMPORTANT to call getInstance() on the main thread,
@@ -563,16 +560,16 @@ public:
// the main thread processes them, only the FIRST such request
// actually constructs the instance -- every subsequent one
// simply returns the existing instance.
- loginfos(classname<DERIVED_TYPE>().c_str(),
- "::getInstance() on main thread");
+ loginfos({classname<DERIVED_TYPE>(),
+ "::getInstance() on main thread"});
return getInstance();
});
// record the dependency chain tracked on THIS thread, not the main
// thread (consider a getInstance() overload with a tag param that
// suppresses dep tracking when dispatched to the main thread)
capture_dependency(instance);
- loginfos(classname<DERIVED_TYPE>().c_str(),
- "::getInstance() returning on requesting thread");
+ loginfos({classname<DERIVED_TYPE>(),
+ "::getInstance() returning on requesting thread"});
return instance;
}
@@ -641,16 +638,16 @@ private:
// For organizational purposes this function shouldn't be called twice
if (lk->mInitState != super::UNINITIALIZED)
{
- super::logerrs("Tried to initialize singleton ",
- super::template classname<DERIVED_TYPE>().c_str(),
- " twice!");
+ super::logerrs({"Tried to initialize singleton ",
+ super::template classname<DERIVED_TYPE>(),
+ " twice!"});
return nullptr;
}
else if (on_main_thread())
{
// on the main thread, simply construct instance while holding lock
- super::logdebugs(super::template classname<DERIVED_TYPE>().c_str(),
- "::initParamSingleton()");
+ super::logdebugs({super::template classname<DERIVED_TYPE>(),
+ "::initParamSingleton()"});
super::constructSingleton(lk, std::forward<Args>(args)...);
return lk->mInstance;
}
@@ -662,8 +659,8 @@ private:
lk->mInitState = super::QUEUED;
// very important to unlock here so main thread can actually process
lk.unlock();
- super::loginfos(super::template classname<DERIVED_TYPE>().c_str(),
- "::initParamSingleton() dispatching to main thread");
+ super::loginfos({super::template classname<DERIVED_TYPE>(),
+ "::initParamSingleton() dispatching to main thread"});
// Normally it would be the height of folly to reference-bind
// 'args' into a lambda to be executed on some other thread! By
// the time that thread executed the lambda, the references would
@@ -674,12 +671,12 @@ private:
// references.
auto instance = LLMainThreadTask::dispatch(
[&](){
- super::loginfos(super::template classname<DERIVED_TYPE>().c_str(),
- "::initParamSingleton() on main thread");
+ super::loginfos({super::template classname<DERIVED_TYPE>(),
+ "::initParamSingleton() on main thread"});
return initParamSingleton_(std::forward<Args>(args)...);
});
- super::loginfos(super::template classname<DERIVED_TYPE>().c_str(),
- "::initParamSingleton() returning on requesting thread");
+ super::loginfos({super::template classname<DERIVED_TYPE>(),
+ "::initParamSingleton() returning on requesting thread"});
return instance;
}
}
@@ -707,14 +704,14 @@ public:
{
case super::UNINITIALIZED:
case super::QUEUED:
- super::logerrs("Uninitialized param singleton ",
- super::template classname<DERIVED_TYPE>().c_str());
+ super::logerrs({"Uninitialized param singleton ",
+ super::template classname<DERIVED_TYPE>()});
break;
case super::CONSTRUCTING:
- super::logerrs("Tried to access param singleton ",
- super::template classname<DERIVED_TYPE>().c_str(),
- " from singleton constructor!");
+ super::logerrs({"Tried to access param singleton ",
+ super::template classname<DERIVED_TYPE>(),
+ " from singleton constructor!"});
break;
case super::INITIALIZING:
@@ -726,8 +723,8 @@ public:
return lk->mInstance;
case super::DELETED:
- super::logerrs("Trying to access deleted param singleton ",
- super::template classname<DERIVED_TYPE>().c_str());
+ super::logerrs({"Trying to access deleted param singleton ",
+ super::template classname<DERIVED_TYPE>()});
break;
}