diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2024-05-03 09:27:16 -0400 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2024-05-03 09:27:16 -0400 |
commit | 922277764d41e96a1c41291272bb70e3a1b8c677 (patch) | |
tree | f1a3aed9d658b4e26bf9c1d18e0bb19531e7649e | |
parent | 5e64fd06a6281eb4b7cc0e30b3d8dae62c264603 (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.cpp | 2 |
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(); }); |