diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2021-10-07 16:45:15 -0400 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2021-10-07 16:45:15 -0400 |
commit | c585ddb75e383cdd994d0d99fed8f2de8f955e3c (patch) | |
tree | 9eeb9b6593d5ef4ab31e4cd4678829113af6426a /indra/llcommon | |
parent | 623ac79120a417ec445ce5c106a907fe46734309 (diff) |
SL-16024: Defend against two threads making "anonymous" WorkQueues.
Also make workqueue_test.cpp more robust.
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/tests/workqueue_test.cpp | 11 | ||||
-rw-r--r-- | indra/llcommon/workqueue.cpp | 18 |
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) |