diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index 2d755407e9..cfcc7a454b 100644
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
@@ -426,6 +426,20 @@ void LLQueuedThread::processRequest(LLQueuedThread::QueuedRequest* req)
// safe to access req.
if (req)
{
+ // Deferred retry requests
+ // Potentially when there is nothing else to do this will loop until the retry time.
+ // note that when there is nothing to do the thread still sleeps normally.
+ if( req->mDeferUntil > LL::WorkQueue::TimePoint::clock::now() )
+ {
+ LL_PROFILE_ZONE_NAMED("qtpr - defer requeue");
+ lockData();
+ req->setStatus(STATUS_QUEUED);
+ mRequestQueue.post([this, req]() { processRequest(req); });
+ unlockData();
+ mIdleThread = true;
+ return;
+ }
+ //
// process request
bool complete = req->processRequest();
@@ -473,21 +487,26 @@ void LLQueuedThread::processRequest(LLQueuedThread::QueuedRequest* req)
llassert(ret);
#else
using namespace std::chrono_literals;
- auto retry_time = LL::WorkQueue::TimePoint::clock::now() + 16ms;
- mRequestQueue.post([=]
- {
- LL_PROFILE_ZONE_NAMED("processRequest - retry");
- if (LL::WorkQueue::TimePoint::clock::now() < retry_time)
- {
- auto sleep_time = std::chrono::duration_cast(retry_time - LL::WorkQueue::TimePoint::clock::now());
+ auto retry_time = LL::WorkQueue::TimePoint::clock::now() + 2ms; // reduce delay on retry
+ // improve retry behaviour
+ // mRequestQueue.post([=]
+ // {
+ // LL_PROFILE_ZONE_NAMED("processRequest - retry");
+ // if (LL::WorkQueue::TimePoint::clock::now() < retry_time)
+ // {
+ // auto sleep_time = std::chrono::duration_cast(retry_time - LL::WorkQueue::TimePoint::clock::now());
- if (sleep_time.count() > 0)
- {
- ms_sleep(sleep_time.count());
- }
- }
- processRequest(req);
- });
+ // if (sleep_time.count() > 0)
+ // {
+ // ms_sleep(sleep_time.count());
+ // }
+ // }
+ // processRequest(req);
+ // });
+ req->defer_until(retry_time);
+ LL_PROFILE_ZONE_NAMED("processRequest - post deferred");
+ mRequestQueue.post([this, req]() { processRequest(req); });
+ //
#endif
}
@@ -565,6 +584,7 @@ LLQueuedThread::QueuedRequest::QueuedRequest(LLQueuedThread::handle_t handle, U3
LLSimpleHashEntry(handle),
mStatus(STATUS_UNKNOWN),
mFlags(flags)
+ ,mDeferUntil(LL::WorkQueue::TimePoint::clock::now()) // handle deffered retries without an enforced sleep
{
}
diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h
index 339299f081..dd2ffa081d 100644
--- a/indra/llcommon/llqueuedthread.h
+++ b/indra/llcommon/llqueuedthread.h
@@ -97,6 +97,10 @@ public:
// NOTE: flags are |'d
mFlags |= flags;
}
+ void defer_until(std::chrono::steady_clock::time_point time)
+ {
+ mDeferUntil = time;
+ }
virtual bool processRequest() = 0; // Return true when request has completed
virtual void finishRequest(bool completed); // Always called from thread after request has completed or aborted
@@ -105,6 +109,7 @@ public:
protected:
LLAtomicBase mStatus;
U32 mFlags;
+ std::chrono::steady_clock::time_point mDeferUntil;
};
//------------------------------------------------------------------------