summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2024-05-03 09:27:16 -0400
committerNat Goodspeed <nat@lindenlab.com>2024-05-03 09:27:16 -0400
commit922277764d41e96a1c41291272bb70e3a1b8c677 (patch)
treef1a3aed9d658b4e26bf9c1d18e0bb19531e7649e
parent5e64fd06a6281eb4b7cc0e30b3d8dae62c264603 (diff)
Prevent LLLater from thrashing on LLCallbackList.
If there is exactly one doPeriodically() entry on LLLater, the mQueue entry is deleted before Periodic::operator()() is called. If Periodic's callable returns false, it reinstates itself on mQueue for a future time. That's okay, because the test for mQueue.empty(), and the consequent disconnect from LLCallbackList, happens only after that Periodic call returns. But at the moment Periodic reinstates itself on mQueue, mQueue happens to be empty. That alerts doAtTime2() to register itself on LLCallbackList -- even though at that moment it's already registered. Semantically that's okay because assigning to the LLLater's LLCallbackList::temp_handle_t should implicitly disconnect the previous connection. But it's pointless to create a new connection and disconnect the old one every time we call that lone Periodic. Add a test for mLive.connected(); that way if we already have an LLCallbackList connection, we retain it instead of replacing it with a new one.
-rw-r--r--indra/llcommon/llcallbacklist.cpp2
1 files changed, 1 insertions, 1 deletions
diff --git a/indra/llcommon/llcallbacklist.cpp b/indra/llcommon/llcallbacklist.cpp
index 19b948a5e1..992c83b4d2 100644
--- a/indra/llcommon/llcallbacklist.cpp
+++ b/indra/llcommon/llcallbacklist.cpp
@@ -152,7 +152,7 @@ LLLater::handle_t LLLater::doAtTime2(nullary_func_t callable, HandleMap::iterato
auto handle{ mQueue.emplace(callable, iter->first, iter->second.second) };
// Now that we have an mQueue handle_type, store it in mHandles entry.
iter->second.first = handle;
- if (first)
+ if (first && ! mLive.connected())
{
// If this is our first entry, register for regular callbacks.
mLive = LLCallbackList::instance().doOnIdleRepeating([this]{ return tick(); });