Avoid dead lock in LLQueuedThread::generateHandle / LLTextureFetchWorker::callbackDecoded
Thead 1:
indra/llcommon/llqueuedthread.cpp:456:
452 if (complete)
453 {
454 lockData(); // This locks LLThread::mRunCondition
455 req->setStatus(STATUS_COMPLETE);
456 req->finishRequest(true);
LLImageDecodeThread::ImageRequest::finishRequest calls:
mResponder->completed(success, mDecodedImageRaw, mDecodedImageAux);
LLTextureFetchWorker::DecodeResponder::completed calls:
worker->callbackDecoded(success, raw, aux);
LLTextureFetchWorker::callbackDecoded calls:
LLMutexLock lock(&mWorkMutex); // This locks LLTextureFetchWorker::mWorkMutex
Thread 2:
LLTextureFetchWorker::doWork calls:
LLMutexLock lock(&mWorkMutex); // This locks LLTextureFetchWorker::mWorkMutex
.
.
.
mDecodeHandle = mFetcher->mImageDecodeThread->decodeImage(mFormattedImage, image_priority, discard, mNeedsAux, new DecodeResponder(mFetcher, mID, this));
LLImageDecodeThread::decodeImage calls:
handle_t handle = generateHandle();
LLQueuedThread::generateHandle calls:
lockData(); // This locks LLThread::mRunCondition
This commit is contained in:
@@ -226,7 +226,8 @@ LLWorkerClass::~LLWorkerClass()
|
||||
llerrs << "LLWorkerClass destroyed with stale work handle" << llendl;
|
||||
}
|
||||
if (workreq->getStatus() != LLWorkerThread::STATUS_ABORTED &&
|
||||
workreq->getStatus() != LLWorkerThread::STATUS_COMPLETE)
|
||||
workreq->getStatus() != LLWorkerThread::STATUS_COMPLETE &&
|
||||
!(workreq->getFlags() & LLWorkerThread::FLAG_LOCKED))
|
||||
{
|
||||
llerrs << "LLWorkerClass destroyed with active worker! Worker Status: " << workreq->getStatus() << llendl;
|
||||
}
|
||||
@@ -350,14 +351,10 @@ bool LLWorkerClass::checkWork(bool aborting)
|
||||
}
|
||||
|
||||
LLQueuedThread::status_t status = workreq->getStatus();
|
||||
if (status == LLWorkerThread::STATUS_ABORTED)
|
||||
if (status == LLWorkerThread::STATUS_COMPLETE || status == LLWorkerThread::STATUS_ABORTED)
|
||||
{
|
||||
complete = true;
|
||||
abort = true;
|
||||
}
|
||||
else if (status == LLWorkerThread::STATUS_COMPLETE)
|
||||
{
|
||||
complete = true;
|
||||
complete = !(workreq->getFlags() & LLWorkerThread::FLAG_LOCKED);
|
||||
abort = status == LLWorkerThread::STATUS_ABORTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user