diff options
author | Loren Shih <seraph@lindenlab.com> | 2009-08-13 16:05:07 +0000 |
---|---|---|
committer | Loren Shih <seraph@lindenlab.com> | 2009-08-13 16:05:07 +0000 |
commit | ed351ca9138ea39b78e871716f12483f53795932 (patch) | |
tree | 3b673855b968f391abd15b3c4f8428104f1a2307 /indra/newview | |
parent | 953aec0613081686f7a56af0e9255f4ce15cf9cc (diff) |
For DEV-37955 : Broken links possible if linked item is cached but baseobj not cached
Major fix to guarantee no broken links. If a link comes through from the cache but its baseobj doesn't also exist in the cache, then don't add the link to memory yet, and uncache the folder.
Reviewed by: Nyx, Vir.
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/llinventorymodel.cpp | 38 | ||||
-rw-r--r-- | indra/newview/llviewerinventory.cpp | 11 | ||||
-rw-r--r-- | indra/newview/llviewerinventory.h | 1 |
3 files changed, 42 insertions, 8 deletions
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index d5d2897383..b27fbbff88 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1786,6 +1786,12 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item) //llinfos << "LLInventoryModel::addItem()" << llendl; if(item) { + // This condition means that we tried to add a link without the baseobj being in memory. + // The item will show up as a broken link. + if (item->getIsBrokenLink()) + { + llwarns << "Add link item without baseobj present ( itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) " << llendl; + } mItemMap[item->getUUID()] = item; //mInventory[item->getUUID()] = item; } @@ -2122,16 +2128,28 @@ bool LLInventoryModel::loadSkeleton( cat_map_t::iterator unparented = mCategoryMap.end(); for(int i = 0; i < count; ++i) { - cat_map_t::iterator cit = mCategoryMap.find(items[i]->getParentUUID()); + LLViewerInventoryItem *item = items[i].get(); + cat_map_t::iterator cit = mCategoryMap.find(item->getParentUUID()); if(cit != unparented) { LLViewerInventoryCategory* cat = cit->second; if(cat->getVersion() != NO_VERSION) { - addItem(items[i]); + if (item->getIsBrokenLink()) + { + llinfos << "Attempted to cached link item without baseobj present ( itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) " << llendl; + child_counts[cat->getUUID()].mValue = -1; // Invalidate this category's cache. + continue; + } + addItem(item); cached_item_count += 1; - ++child_counts[cat->getUUID()]; + + // If this category had any broken links, keep it invalidated. + if (child_counts[cat->getUUID()].mValue != -1) + { + ++child_counts[cat->getUUID()]; + } } } } @@ -2161,12 +2179,16 @@ bool LLInventoryModel::loadSkeleton( the_count = child_counts.find(cat->getUUID()); if(the_count != no_child_counts) { - cat->setDescendentCount((*the_count).second.mValue); - } - else - { - cat->setDescendentCount(0); + S32 num_descendents = (*the_count).second.mValue; + + // -1 means that one of the children was a broken link, so we can't consider this folder successfully cached. + if (num_descendents != -1) + { + cat->setDescendentCount(num_descendents); + continue; + } } + cat->setDescendentCount(0); } } diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 78e8f084c7..9a090be76a 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1185,6 +1185,17 @@ U32 LLViewerInventoryItem::getCRC32() const return LLInventoryItem::getCRC32(); } +// This returns true if the item that this item points to +// doesn't exist in memory (i.e. LLInventoryModel). The baseitem +// might still be in the database but just not loaded yet. +bool LLViewerInventoryItem::getIsBrokenLink() const +{ + // If the item's type resolves to be a link, that means either: + // A. It wasn't able to perform indirection, i.e. the baseobj doesn't exist in memory. + // B. It's pointing to another link, which is illegal. + return LLAssetType::lookupIsLinkType(getType()); +} + const LLViewerInventoryItem *LLViewerInventoryItem::getLinkedItem() const { if (mType == LLAssetType::AT_LINK) diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 10309d023b..8920fb053b 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -141,6 +141,7 @@ public: }; LLTransactionID getTransactionID() const { return mTransactionID; } + bool getIsBrokenLink() const; // true if the baseitem this points to doesn't exist in memory. const LLViewerInventoryItem *getLinkedItem() const; const LLViewerInventoryCategory *getLinkedCategory() const; |