summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreyL ProductEngine <alihatskiy@productengine.com>2016-10-19 02:09:47 +0300
committerAndreyL ProductEngine <alihatskiy@productengine.com>2016-10-19 02:09:47 +0300
commit2e52d12ef1ecc53f1affdf7b6d2150e9256eee65 (patch)
tree8b73372ba63049b0ef9c5ce42bd78d5f5e01cc6b
parentf75ea457c836d73d6bdbbeed77536c74c1482f29 (diff)
MAINT-6819 Fix for LLTextureCacheRemoteWorker::doWrite crash
-rw-r--r--indra/newview/lltexturecache.cpp167
1 files changed, 100 insertions, 67 deletions
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 36c4f0d516..a541273621 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -547,10 +547,18 @@ bool LLTextureCacheRemoteWorker::doWrite()
// First state / stage : check that what we're trying to cache is in an OK shape
if (mState == INIT)
{
- llassert_always(mOffset == 0); // We currently do not support write offsets
- llassert_always(mDataSize > 0); // Things will go badly wrong if mDataSize is nul or negative...
- llassert_always(mImageSize >= mDataSize);
- mState = CACHE;
+ if ((mOffset != 0) // We currently do not support write offsets
+ || (mDataSize <= 0) // Things will go badly wrong if mDataSize is nul or negative...
+ || (mImageSize < mDataSize))
+ {
+ LL_WARNS() << "INIT state check failed" << LL_ENDL;
+ mDataSize = -1; // failed
+ done = true;
+ }
+ else
+ {
+ mState = CACHE;
+ }
}
// No LOCAL state for write(): because it doesn't make much sense to cache a local file...
@@ -559,7 +567,7 @@ bool LLTextureCacheRemoteWorker::doWrite()
if (!done && (mState == CACHE))
{
bool alreadyCached = false;
- LLTextureCache::Entry entry ;
+ LLTextureCache::Entry entry;
// Checks if this image is already in the entry list
idx = mCache->getHeaderCacheEntry(mID, entry);
@@ -571,107 +579,132 @@ bool LLTextureCacheRemoteWorker::doWrite()
// (almost always) write to the fast cache.
if (mRawImage->getDataSize())
{
- llassert_always(mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel));
+ if(!mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel))
+ {
+ LL_WARNS() << "writeToFastCache failed" << LL_ENDL;
+ mDataSize = -1; // failed
+ done = true;
+ }
+ }
}
}
- }
else
{
alreadyCached = mCache->updateEntry(idx, entry, mImageSize, mDataSize); // update the existing entry.
}
- if (idx < 0)
- {
- LL_WARNS() << "LLTextureCacheWorker: " << mID
- << " Unable to create header entry for writing!" << LL_ENDL;
- mDataSize = -1; // failed
- done = true;
- }
- else
+ if (!done)
{
- if (alreadyCached && (mDataSize <= TEXTURE_CACHE_ENTRY_SIZE))
+ if (idx < 0)
{
- // Small texture already cached case: we're done with writing
+ LL_WARNS() << "LLTextureCacheWorker: " << mID
+ << " Unable to create header entry for writing!" << LL_ENDL;
+ mDataSize = -1; // failed
done = true;
}
else
{
- // If the texture has already been cached, we don't resave the header and go directly to the body part
- mState = alreadyCached ? BODY : HEADER;
+ if (alreadyCached && (mDataSize <= TEXTURE_CACHE_ENTRY_SIZE))
+ {
+ // Small texture already cached case: we're done with writing
+ done = true;
+ }
+ else
+ {
+ // If the texture has already been cached, we don't resave the header and go directly to the body part
+ mState = alreadyCached ? BODY : HEADER;
+ }
}
}
}
+
// Third stage / state : write the header record in the header file (texture.cache)
if (!done && (mState == HEADER))
{
- llassert_always(idx >= 0); // we need an entry here or storing the header makes no sense
- S32 offset = idx * TEXTURE_CACHE_ENTRY_SIZE; // skip to the correct spot in the header file
- S32 size = TEXTURE_CACHE_ENTRY_SIZE; // record size is fixed for the header
- S32 bytes_written;
-
- if (mDataSize < TEXTURE_CACHE_ENTRY_SIZE)
+ if (idx < 0) // we need an entry here or storing the header makes no sense
{
- // We need to write a full record in the header cache so, if the amount of data is smaller
- // than a record, we need to transfer the data to a buffer padded with 0 and write that
- U8* padBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), TEXTURE_CACHE_ENTRY_SIZE);
- memset(padBuffer, 0, TEXTURE_CACHE_ENTRY_SIZE); // Init with zeros
- memcpy(padBuffer, mWriteData, mDataSize); // Copy the write buffer
- bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, padBuffer, offset, size, mCache->getLocalAPRFilePool());
- FREE_MEM(LLImageBase::getPrivatePool(), padBuffer);
+ LL_WARNS() << "index check failed" << LL_ENDL;
+ mDataSize = -1; // failed
+ done = true;
}
else
{
- // Write the header record (== first TEXTURE_CACHE_ENTRY_SIZE bytes of the raw file) in the header file
- bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, mWriteData, offset, size, mCache->getLocalAPRFilePool());
- }
+ S32 offset = idx * TEXTURE_CACHE_ENTRY_SIZE; // skip to the correct spot in the header file
+ S32 size = TEXTURE_CACHE_ENTRY_SIZE; // record size is fixed for the header
+ S32 bytes_written;
- if (bytes_written <= 0)
- {
- LL_WARNS() << "LLTextureCacheWorker: " << mID
+ if (mDataSize < TEXTURE_CACHE_ENTRY_SIZE)
+ {
+ // We need to write a full record in the header cache so, if the amount of data is smaller
+ // than a record, we need to transfer the data to a buffer padded with 0 and write that
+ U8* padBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), TEXTURE_CACHE_ENTRY_SIZE);
+ memset(padBuffer, 0, TEXTURE_CACHE_ENTRY_SIZE); // Init with zeros
+ memcpy(padBuffer, mWriteData, mDataSize); // Copy the write buffer
+ bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, padBuffer, offset, size, mCache->getLocalAPRFilePool());
+ FREE_MEM(LLImageBase::getPrivatePool(), padBuffer);
+ }
+ else
+ {
+ // Write the header record (== first TEXTURE_CACHE_ENTRY_SIZE bytes of the raw file) in the header file
+ bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, mWriteData, offset, size, mCache->getLocalAPRFilePool());
+ }
+
+ if (bytes_written <= 0)
+ {
+ LL_WARNS() << "LLTextureCacheWorker: " << mID
<< " Unable to write header entry!" << LL_ENDL;
- mDataSize = -1; // failed
- done = true;
- }
+ mDataSize = -1; // failed
+ done = true;
+ }
- // If we wrote everything (may be more with padding) in the header cache,
- // we're done so we don't have a body to store
- if (mDataSize <= bytes_written)
- {
- done = true;
- }
- else
- {
- mState = BODY;
+ // If we wrote everything (may be more with padding) in the header cache,
+ // we're done so we don't have a body to store
+ if (mDataSize <= bytes_written)
+ {
+ done = true;
+ }
+ else
+ {
+ mState = BODY;
+ }
}
}
// Fourth stage / state : write the body file, i.e. the rest of the texture in a "UUID" file name
if (!done && (mState == BODY))
{
- llassert(mDataSize > TEXTURE_CACHE_ENTRY_SIZE); // wouldn't make sense to be here otherwise...
- S32 file_size = mDataSize - TEXTURE_CACHE_ENTRY_SIZE;
-
+ if (mDataSize <= TEXTURE_CACHE_ENTRY_SIZE) // wouldn't make sense to be here otherwise...
{
- // build the cache file name from the UUID
- std::string filename = mCache->getTextureFileName(mID);
-// LL_INFOS() << "Writing Body: " << filename << " Bytes: " << file_offset+file_size << LL_ENDL;
- S32 bytes_written = LLAPRFile::writeEx( filename,
- mWriteData + TEXTURE_CACHE_ENTRY_SIZE,
- 0, file_size,
- mCache->getLocalAPRFilePool());
- if (bytes_written <= 0)
+ LL_WARNS() << "mDataSize check failed" << LL_ENDL;
+ mDataSize = -1; // failed
+ done = true;
+ }
+ else
+ {
+ S32 file_size = mDataSize - TEXTURE_CACHE_ENTRY_SIZE;
+
{
- LL_WARNS() << "LLTextureCacheWorker: " << mID
+ // build the cache file name from the UUID
+ std::string filename = mCache->getTextureFileName(mID);
+ // LL_INFOS() << "Writing Body: " << filename << " Bytes: " << file_offset+file_size << LL_ENDL;
+ S32 bytes_written = LLAPRFile::writeEx(filename,
+ mWriteData + TEXTURE_CACHE_ENTRY_SIZE,
+ 0, file_size,
+ mCache->getLocalAPRFilePool());
+ if (bytes_written <= 0)
+ {
+ LL_WARNS() << "LLTextureCacheWorker: " << mID
<< " incorrect number of bytes written to body: " << bytes_written
<< " / " << file_size << LL_ENDL;
- mDataSize = -1; // failed
- done = true;
+ mDataSize = -1; // failed
+ done = true;
+ }
}
+
+ // Nothing else to do at that point...
+ done = true;
}
-
- // Nothing else to do at that point...
- done = true;
}
mRawImage = NULL;