summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2021-10-07 16:45:15 -0400
committerNat Goodspeed <nat@lindenlab.com>2021-10-07 16:45:15 -0400
commitc585ddb75e383cdd994d0d99fed8f2de8f955e3c (patch)
tree9eeb9b6593d5ef4ab31e4cd4678829113af6426a /indra
parent623ac79120a417ec445ce5c106a907fe46734309 (diff)
SL-16024: Defend against two threads making "anonymous" WorkQueues.
Also make workqueue_test.cpp more robust.
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/tests/workqueue_test.cpp11
-rw-r--r--indra/llcommon/workqueue.cpp18
2 files changed, 22 insertions, 7 deletions
diff --git a/indra/llcommon/tests/workqueue_test.cpp b/indra/llcommon/tests/workqueue_test.cpp
index ab1cae6c14..d5405400fd 100644
--- a/indra/llcommon/tests/workqueue_test.cpp
+++ b/indra/llcommon/tests/workqueue_test.cpp
@@ -103,12 +103,13 @@ namespace tut
Shared result = data.get();
ensure_equals("called wrong number of times", result.size(), 3);
// postEvery() assumes you want the first call to happen right away.
- // Inject a fake start time that's (interval) earlier than that, to
- // make our too early/too late tests uniform for all entries.
- result.push_front(start - interval);
- for (size_t i = 1; i < result.size(); ++i)
+ // Pretend our start time was (interval) earlier than that, to make
+ // our too early/too late tests uniform for all entries.
+ start -= interval;
+ for (size_t i = 0; i < result.size(); ++i)
{
- auto diff = (result[i] - result[i-1]);
+ auto diff = result[i] - start;
+ start += interval;
try
{
ensure(STRINGIZE("call " << i << " too soon"), diff >= interval);
diff --git a/indra/llcommon/workqueue.cpp b/indra/llcommon/workqueue.cpp
index 15e292fb43..ffc9a97dc0 100644
--- a/indra/llcommon/workqueue.cpp
+++ b/indra/llcommon/workqueue.cpp
@@ -17,10 +17,15 @@
// std headers
// external library headers
// other Linden headers
+#include "llcoros.h"
+#include LLCOROS_MUTEX_HEADER
#include "llerror.h"
#include "llexception.h"
#include "stringize.h"
+using Mutex = LLCoros::Mutex;
+using Lock = LLCoros::LockType;
+
LL::WorkQueue::WorkQueue(const std::string& name):
super(makeName(name))
{
@@ -83,8 +88,17 @@ std::string LL::WorkQueue::makeName(const std::string& name)
if (! name.empty())
return name;
- static thread_local U32 discriminator = 0;
- return STRINGIZE("WorkQueue" << discriminator++);
+ static U32 discriminator = 0;
+ static Mutex mutex;
+ U32 num;
+ {
+ // Protect discriminator from concurrent access by different threads.
+ // It can't be thread_local, else two racing threads will come up with
+ // the same name.
+ Lock lk(mutex);
+ num = discriminator++;
+ }
+ return STRINGIZE("WorkQueue" << num);
}
void LL::WorkQueue::callWork(const Queue::DataTuple& work)