[sldev] Question/possible bug with on LLTextureFetch mutex use
Vex Streeter
vexstreeter at gmail.com
Fri Sep 25 10:24:25 PDT 2009
I've been reading the texture cache code for the last week or so, and I
see something that I don't quite understand - looks like a bug to me,
but I'm no expert on this code so I'm not comfortable enough to generate
a jira entry:
// lltexturefetch.cpp (current snowglobe, svn 2574) line 1471-
void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker)
{
LLMutexLock lock(&mNetworkQueueMutex);
if (mRequestMap.find(worker->mID) != mRequestMap.end())
{
// only add to the queue if in the request map
// i.e. a delete has not been requested
mNetworkQueue.insert(worker->mID);
}
for (cancel_queue_t::iterator iter1 = mCancelQueue.begin();
iter1 != mCancelQueue.end(); ++iter1)
{
iter1->second.erase(worker->mID);
}
}
Most accesses to mRequestMap are protected by locking mQueueMutex, but I
don't see how that lock could be held here - addToNetworkQueue is called
by LLTextureFetchWorker::doWork, which only holds mWorkMutex. So my
questions are:
1. Is mQueueMutex actually held somehow here, making it safe to call
find() and end() on mRequestMap?
2. or are find() and end() somehow safe to invoke without being locked?
Seems unlikely given the semantics of the usual std::map<>
implementation and that the nearby getWorker appears to always be called
with mQueueMutex held.
The failure mode would be find()==end() when it really is present,
leading to a request that never got added to the network queue and never
got canceled (e.g. a texture that isn't retrieved?). mRequestMap is an
std:map, which is a non-trivial datastructure - it isn't much of a
stretch to imagine situations where the find() gets lost in the tree
while an insert is splitting (or even worse, rebalancing - I don't know
if std:map rebalances)
Hoping this is useful. Cheers,
Vex
More information about the SLDev
mailing list