diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2019-12-10 10:56:24 -0500 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2020-03-25 19:24:25 -0400 |
commit | 39e7b48317e3f0fe37d7398099ab1e38b97963bf (patch) | |
tree | 7734474fcadf89bfeeea1dbc099ccc33b3716ef6 /indra | |
parent | 3cd2beb97ef0d368d47b0b7efd242b3c709d01af (diff) |
DRTVWR-476: Make llcoro::logname() distinguish different threads.
Actually, introduce static LLCoros::logname() and make the namespaced free
function an alias for that.
Because CoroData is a subclass of LLInstanceTracker with a key, every instance
requires a distinct key. That conflicts with our "getName() returns empty
string for default coroutine on thread" convention. Introduce a new CoroData
constructor, specifically for the default coroutine on each thread, that
initializes the getName() name to empty string while providing a distinct
"mainN" key. Make get_CoroData() use that new constructor for its thread_local
instance, passing an atomic<int> incremented each time we initialize one for a
new thread.
Then LLCoros::logname() returns either the getName() name or the key.
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llcommon/llcoros.cpp | 28 | ||||
-rw-r--r-- | indra/llcommon/llcoros.h | 15 |
2 files changed, 33 insertions, 10 deletions
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 9e0cceda2b..adb86c4e0b 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -34,6 +34,7 @@ #include "llcoros.h" // STL headers // std headers +#include <atomic> // external library headers #include <boost/bind.hpp> #include <boost/fiber/fiber.hpp> @@ -73,10 +74,9 @@ LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller) // canonical values. if (! current) { - // It's tempting to provide a distinct name for each thread's "main - // coroutine." But as getName() has always returned the empty string - // to mean "not in a coroutine," empty string should suffice here. - static thread_local CoroData sMain(""); + static std::atomic<int> which_thread(0); + // Use alternate CoroData constructor. + static thread_local CoroData sMain(which_thread++); // We need not reset() the local_ptr to this instance; we'll simply // find it again every time we discover that current is null. current = &sMain; @@ -198,6 +198,13 @@ std::string LLCoros::getName() return get_CoroData("getName()").mName; } +//static +std::string LLCoros::logname() +{ + LLCoros::CoroData& data(get_CoroData("logname()")); + return data.mName.empty()? data.getKey() : data.mName; +} + void LLCoros::setStackSize(S32 stacksize) { LL_DEBUGS("LLCoros") << "Setting coroutine stack size to " << stacksize << LL_ENDL; @@ -353,3 +360,16 @@ LLCoros::CoroData::CoroData(const std::string& name): mCreationTime(LLTimer::getTotalSeconds()) { } + +LLCoros::CoroData::CoroData(int n): + // This constructor is used for the thread_local instance belonging to the + // default coroutine on each thread. We must give each one a different + // LLInstanceTracker key because LLInstanceTracker's map spans all + // threads, but we want the default coroutine on each thread to have the + // empty string as its visible name because some consumers test for that. + LLInstanceTracker<CoroData, std::string>("main" + stringize(n)), + mName(), + mConsuming(false), + mCreationTime(LLTimer::getTotalSeconds()) +{ +} diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h index 2e4cd8ccad..95859198d4 100644 --- a/indra/llcommon/llcoros.h +++ b/indra/llcommon/llcoros.h @@ -143,6 +143,13 @@ public: static std::string getName(); /** + * This variation returns a name suitable for log messages: the explicit + * name for an explicitly-launched coroutine, or "mainN" for the default + * coroutine on a thread. + */ + static std::string logname(); + + /** * For delayed initialization. To be clear, this will only affect * coroutines launched @em after this point. The underlying facility * provides no way to alter the stack size of any running coroutine. @@ -272,6 +279,7 @@ private: struct CoroData: public LLInstanceTracker<CoroData, std::string> { CoroData(const std::string& name); + CoroData(int n); // tweaked name of the current coroutine const std::string mName; @@ -292,12 +300,7 @@ namespace llcoro { inline -std::string logname() -{ - static std::string main("main"); - std::string name(LLCoros::getName()); - return name.empty()? main : name; -} +std::string logname() { return LLCoros::logname(); } } // llcoro |