diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index b84d40df31b3266054f2b4b869836239af3c354e..0f9e505e75bbc9e7a2c5c5c91ab428ee05611e8f 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -35,7 +35,8 @@ std::atomic< U32 > sImageThreads = 0; class PoolWorkerThread final : public LLThread { public: - PoolWorkerThread(std::string name) : LLThread(name), mRequestQueue(256) + PoolWorkerThread(std::string name) : LLThread(name), + mCurrentRequest(NULL) { } @@ -43,36 +44,40 @@ class PoolWorkerThread final : public LLThread { while (!isQuitting()) { - checkPause(); - - LLImageDecodeThread::ImageRequest* req = nullptr; - while (!isQuitting() && mRequestQueue.tryPop(req)) - { - if (req) - { - req->processRequestIntern(); - } - } + auto *pReq = mCurrentRequest.exchange(nullptr); + + if (pReq) + pReq->processRequestIntern(); + checkPause(); } } + bool isBusy() + { + auto *pReq = mCurrentRequest.load(); + if (!pReq) + return false; + + auto status = pReq->getStatus(); + + return status == LLQueuedThread::STATUS_QUEUED || status == LLQueuedThread::STATUS_INPROGRESS; + } bool runCondition() - { - return mRequestQueue.size() > 0; + { + return mCurrentRequest != NULL; } bool setRequest(LLImageDecodeThread::ImageRequest* req) { - bool bSuccess = mRequestQueue.tryPush(req); - if(bSuccess) - { - wake(); - } + LLImageDecodeThread::ImageRequest* pOld{ nullptr }; + bool bSuccess = mCurrentRequest.compare_exchange_strong(pOld, req); + wake(); + return bSuccess; } private: - LLThreadSafeQueue<LLImageDecodeThread::ImageRequest*> mRequestQueue; + std::atomic<LLImageDecodeThread::ImageRequest*> mCurrentRequest; }; //---------------------------------------------------------------------------- @@ -344,13 +349,14 @@ bool LLImageDecodeThread::ImageRequest::tut_isOK() bool LLImageDecodeThread::enqueRequest(ImageRequest * req) { + for(size_t num_tries = 0, pool_size = mThreadPool.size(); num_tries < pool_size; ++num_tries) { - if (mLastPoolAllocation >= mThreadPool.size()) + if (mLastPoolAllocation >= pool_size) { mLastPoolAllocation = 0; } auto& thread = mThreadPool[mLastPoolAllocation++]; - if (thread->setRequest(req)) + if (!thread->isBusy() && thread->setRequest(req)) { return true; }