diff options
-rwxr-xr-x | indra/newview/llappcorehttp.cpp | 9 | ||||
-rwxr-xr-x | indra/newview/llappcorehttp.h | 18 | ||||
-rwxr-xr-x | indra/newview/llinventorymodel.cpp | 601 | ||||
-rwxr-xr-x | indra/newview/llinventorymodel.h | 82 | ||||
-rwxr-xr-x | indra/newview/llinventorymodelbackgroundfetch.cpp | 740 | ||||
-rwxr-xr-x | indra/newview/llinventorymodelbackgroundfetch.h | 28 | ||||
-rwxr-xr-x | indra/newview/llinventoryobserver.cpp | 3 | ||||
-rw-r--r-- | indra/newview/llsnapshotlivepreview.cpp | 16 | ||||
-rwxr-xr-x | indra/newview/llviewerinventory.cpp | 128 | ||||
-rwxr-xr-x | indra/newview/llviewermenu.cpp | 4 |
10 files changed, 1034 insertions, 595 deletions
diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp index 464e60948a..2b7d91b5ff 100755 --- a/indra/newview/llappcorehttp.cpp +++ b/indra/newview/llappcorehttp.cpp @@ -60,7 +60,7 @@ static const struct "other" }, { // AP_TEXTURE - 8, 1, 12, 0, true, + 8, 1, 12, 0, true, "TextureFetchConcurrency", "texture fetch" }, @@ -70,7 +70,7 @@ static const struct "mesh fetch" }, { // AP_MESH2 - 8, 1, 32, 100, true, + 8, 1, 32, 100, true, "Mesh2MaxConcurrentRequests", "mesh2 fetch" }, @@ -88,6 +88,11 @@ static const struct 32, 32, 32, 0, false, "", "long poll" + }, + { // AP_INVENTORY + 4, 1, 4, 0, false, + "", + "inventory" } }; diff --git a/indra/newview/llappcorehttp.h b/indra/newview/llappcorehttp.h index 9ad4eb4b30..e822a40300 100755 --- a/indra/newview/llappcorehttp.h +++ b/indra/newview/llappcorehttp.h @@ -64,7 +64,7 @@ public: /// Texture fetching policy class. Used to /// download textures via capability or SSA /// baking service. Deep queueing of requests. - /// Do not share. + /// Do not share. GET requests only. /// /// Destination: simhost:12046 & bake-texture:80 /// Protocol: http: @@ -92,7 +92,8 @@ public: /// download textures via 'GetMesh2' capability. /// Used when fetch request (typically one LOD) /// is 'small', currently defined as 2MB. - /// Very deeply queued. Do not share. + /// Very deeply queued. Do not share. GET + /// requests only. /// /// Destination: simhost:12046 /// Protocol: http: @@ -150,6 +151,19 @@ public: /// Pipelined: no AP_LONG_POLL, + /// Inventory operations (really Capabilities- + /// related operations). Mix of high-priority + /// and low-priority operations. + /// + /// Destination: simhost:12043 + /// Protocol: https: + /// Transfer size: KB-MB + /// Long poll: no + /// Concurrency: high + /// Request rate: high + /// Pipelined: no + AP_INVENTORY, + AP_COUNT // Must be last }; diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 14ca0095ae..2dd31f047f 100755 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2014, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,6 +25,9 @@ */ #include "llviewerprecompiledheaders.h" + +#include <typeinfo> + #include "llinventorymodel.h" #include "llaisapi.h" @@ -50,7 +53,9 @@ #include "llvoavatarself.h" #include "llgesturemgr.h" #include "llsdutil.h" -#include <typeinfo> +#include "bufferarray.h" +#include "bufferstream.h" +#include "llsdserialize.h" //#define DIFF_INVENTORY_FILES #ifdef DIFF_INVENTORY_FILES @@ -67,7 +72,14 @@ BOOL LLInventoryModel::sFirstTimeInViewer2 = TRUE; ///---------------------------------------------------------------------------- //BOOL decompress_file(const char* src_filename, const char* dst_filename); -const char CACHE_FORMAT_STRING[] = "%s.inv"; +static const char CACHE_FORMAT_STRING[] = "%s.inv"; +static const char * const LOG_INV("Inventory"); + +static std::string dumpResponse() +{ + return std::string("ADD SOMETHING MEANINGFUL HERE"); +} + struct InventoryIDPtrLess { @@ -125,24 +137,32 @@ LLInventoryModel gInventory; // Default constructor LLInventoryModel::LLInventoryModel() -: mModifyMask(LLInventoryObserver::ALL), - mChangedItemIDs(), +: // These are now ordered, keep them that way. mBacklinkMMap(), + mIsAgentInvUsable(false), + mRootFolderID(), + mLibraryRootFolderID(), + mLibraryOwnerID(), mCategoryMap(), mItemMap(), - mCategoryLock(), - mItemLock(), - mLastItem(NULL), mParentChildCategoryTree(), mParentChildItemTree(), - mObservers(), - mRootFolderID(), - mLibraryRootFolderID(), - mLibraryOwnerID(), + mLastItem(NULL), mIsNotifyObservers(FALSE), - mIsAgentInvUsable(false) -{ -} + mModifyMask(LLInventoryObserver::ALL), + mChangedItemIDs(), + mObservers(), + mHttpRequestFG(NULL), + mHttpRequestBG(NULL), + mHttpOptions(NULL), + mHttpHeaders(NULL), + mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID), + mHttpPriorityFG(0), + mHttpPriorityBG(0), + mCategoryLock(), + mItemLock() +{} + // Destroys the object LLInventoryModel::~LLInventoryModel() @@ -162,6 +182,22 @@ void LLInventoryModel::cleanupInventory() delete observer; } mObservers.clear(); + + // Run down HTTP transport + if (mHttpHeaders) + { + mHttpHeaders->release(); + mHttpHeaders = NULL; + } + if (mHttpOptions) + { + mHttpOptions->release(); + mHttpOptions = NULL; + } + delete mHttpRequestFG; + mHttpRequestFG = NULL; + delete mHttpRequestBG; + mHttpRequestBG = NULL; } // This is a convenience function to check if one object has a parent @@ -253,7 +289,7 @@ bool LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& LLInventoryObject *parent_object = getObject(object->getParentUUID()); if (!parent_object) { - LL_WARNS() << "unable to trace topmost ancestor, missing item for uuid " << object->getParentUUID() << LL_ENDL; + LL_WARNS(LOG_INV) << "unable to trace topmost ancestor, missing item for uuid " << object->getParentUUID() << LL_ENDL; return false; } object = parent_object; @@ -508,7 +544,7 @@ public: protected: virtual void httpFailure() { - LL_WARNS("InvAPI") << dumpResponse() << LL_ENDL; + LL_WARNS(LOG_INV) << dumpResponse() << LL_ENDL; } virtual void httpSuccess() @@ -522,7 +558,7 @@ protected: } LLUUID category_id = content["folder_id"].asUUID(); - LL_DEBUGS("Avatar") << ll_pretty_print_sd(content) << LL_ENDL; + LL_DEBUGS(LOG_INV) << ll_pretty_print_sd(content) << LL_ENDL; // Add the category to the internal representation LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory( category_id, @@ -560,13 +596,13 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id, LLUUID id; if(!isInventoryUsable()) { - LL_WARNS() << "Inventory is broken." << LL_ENDL; + LL_WARNS(LOG_INV) << "Inventory is broken." << LL_ENDL; return id; } if(LLFolderType::lookup(preferred_type) == LLFolderType::badLookup()) { - LL_DEBUGS() << "Attempt to create undefined category." << LL_ENDL; + LL_DEBUGS(LOG_INV) << "Attempt to create undefined category." << LL_ENDL; return id; } @@ -599,7 +635,7 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id, request["message"] = "CreateInventoryCategory"; request["payload"] = body; - LL_DEBUGS("Avatar") << "create category request: " << ll_pretty_print_sd(request) << LL_ENDL; + LL_DEBUGS(LOG_INV) << "create category request: " << ll_pretty_print_sd(request) << LL_ENDL; // viewer_region->getCapAPI().post(request); LLHTTPClient::post( url, @@ -820,7 +856,7 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask) if(!isInventoryUsable()) { - LL_WARNS() << "Inventory is broken." << LL_ENDL; + LL_WARNS(LOG_INV) << "Inventory is broken." << LL_ENDL; return mask; } @@ -883,7 +919,7 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask) } else { - LL_WARNS() << "Couldn't find parent-child item tree for " << new_item->getName() << LL_ENDL; + LL_WARNS(LOG_INV) << "Couldn't find parent-child item tree for " << new_item->getName() << LL_ENDL; } } else @@ -912,8 +948,8 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask) else { // Whoops! No such parent, make one. - LL_INFOS() << "Lost item: " << new_item->getUUID() << " - " - << new_item->getName() << LL_ENDL; + LL_INFOS(LOG_INV) << "Lost item: " << new_item->getUUID() << " - " + << new_item->getName() << LL_ENDL; parent_id = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); new_item->setParent(parent_id); item_array = get_ptr_in_map(mParentChildItemTree, parent_id); @@ -926,7 +962,7 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask) } else { - LL_WARNS() << "Lost and found Not there!!" << LL_ENDL; + LL_WARNS(LOG_INV) << "Lost and found Not there!!" << LL_ENDL; } } } @@ -1000,7 +1036,7 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat, U32 if(!isInventoryUsable()) { - LL_WARNS() << "Inventory is broken." << LL_ENDL; + LL_WARNS(LOG_INV) << "Inventory is broken." << LL_ENDL; return; } @@ -1062,17 +1098,17 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat, U32 void LLInventoryModel::moveObject(const LLUUID& object_id, const LLUUID& cat_id) { - LL_DEBUGS() << "LLInventoryModel::moveObject()" << LL_ENDL; + LL_DEBUGS(LOG_INV) << "LLInventoryModel::moveObject()" << LL_ENDL; if(!isInventoryUsable()) { - LL_WARNS() << "Inventory is broken." << LL_ENDL; + LL_WARNS(LOG_INV) << "Inventory is broken." << LL_ENDL; return; } if((object_id == cat_id) || !is_in_map(mCategoryMap, cat_id)) { - LL_WARNS() << "Could not move inventory object " << object_id << " to " - << cat_id << LL_ENDL; + LL_WARNS(LOG_INV) << "Could not move inventory object " << object_id << " to " + << cat_id << LL_ENDL; return; } LLPointer<LLViewerInventoryCategory> cat = getCategory(object_id); @@ -1108,14 +1144,14 @@ void LLInventoryModel::changeItemParent(LLViewerInventoryItem* item, { if (item->getParentUUID() == new_parent_id) { - LL_DEBUGS("Inventory") << "'" << item->getName() << "' (" << item->getUUID() - << ") is already in folder " << new_parent_id << LL_ENDL; + LL_DEBUGS(LOG_INV) << "'" << item->getName() << "' (" << item->getUUID() + << ") is already in folder " << new_parent_id << LL_ENDL; } else { - LL_INFOS("Inventory") << "Moving '" << item->getName() << "' (" << item->getUUID() - << ") from " << item->getParentUUID() << " to folder " - << new_parent_id << LL_ENDL; + LL_INFOS(LOG_INV) << "Moving '" << item->getName() << "' (" << item->getUUID() + << ") from " << item->getParentUUID() << " to folder " + << new_parent_id << LL_ENDL; LLInventoryModel::update_list_t update; LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1); update.push_back(old_folder); @@ -1171,7 +1207,7 @@ void LLInventoryModel::onAISUpdateReceived(const std::string& context, const LLS AISUpdate ais_update(update); // parse update llsd into stuff to do. ais_update.doUpdate(); // execute the updates in the appropriate order. - LL_INFOS() << "elapsed: " << timer.getElapsedTimeF32() << LL_ENDL; + LL_INFOS(LOG_INV) << "elapsed: " << timer.getElapsedTimeF32() << LL_ENDL; } // Does not appear to be used currently. @@ -1180,7 +1216,7 @@ void LLInventoryModel::onItemUpdated(const LLUUID& item_id, const LLSD& updates, U32 mask = LLInventoryObserver::NONE; LLPointer<LLViewerInventoryItem> item = gInventory.getItem(item_id); - LL_DEBUGS("Inventory") << "item_id: [" << item_id << "] name " << (item ? item->getName() : "(NOT FOUND)") << LL_ENDL; + LL_DEBUGS(LOG_INV) << "item_id: [" << item_id << "] name " << (item ? item->getName() : "(NOT FOUND)") << LL_ENDL; if(item) { for (LLSD::map_const_iterator it = updates.beginMap(); @@ -1188,19 +1224,19 @@ void LLInventoryModel::onItemUpdated(const LLUUID& item_id, const LLSD& updates, { if (it->first == "name") { - LL_INFOS() << "Updating name from " << item->getName() << " to " << it->second.asString() << LL_ENDL; + LL_INFOS(LOG_INV) << "Updating name from " << item->getName() << " to " << it->second.asString() << LL_ENDL; item->rename(it->second.asString()); mask |= LLInventoryObserver::LABEL; } else if (it->first == "desc") { - LL_INFOS() << "Updating description from " << item->getActualDescription() - << " to " << it->second.asString() << LL_ENDL; + LL_INFOS(LOG_INV) << "Updating description from " << item->getActualDescription() + << " to " << it->second.asString() << LL_ENDL; item->setDescription(it->second.asString()); } else { - LL_ERRS() << "unhandled updates for field: " << it->first << LL_ENDL; + LL_ERRS(LOG_INV) << "unhandled updates for field: " << it->first << LL_ENDL; } } mask |= LLInventoryObserver::INTERNAL; @@ -1211,7 +1247,7 @@ void LLInventoryModel::onItemUpdated(const LLUUID& item_id, const LLSD& updates, LLInventoryModel::LLCategoryUpdate up(item->getParentUUID(), 0); accountForUpdate(up); } - gInventory.notifyObservers(); // do we want to be able to make this optional? + notifyObservers(); // do we want to be able to make this optional? } } @@ -1221,7 +1257,7 @@ void LLInventoryModel::onCategoryUpdated(const LLUUID& cat_id, const LLSD& updat U32 mask = LLInventoryObserver::NONE; LLPointer<LLViewerInventoryCategory> cat = gInventory.getCategory(cat_id); - LL_DEBUGS("Inventory") << "cat_id: [" << cat_id << "] name " << (cat ? cat->getName() : "(NOT FOUND)") << LL_ENDL; + LL_DEBUGS(LOG_INV) << "cat_id: [" << cat_id << "] name " << (cat ? cat->getName() : "(NOT FOUND)") << LL_ENDL; if(cat) { for (LLSD::map_const_iterator it = updates.beginMap(); @@ -1229,18 +1265,18 @@ void LLInventoryModel::onCategoryUpdated(const LLUUID& cat_id, const LLSD& updat { if (it->first == "name") { - LL_INFOS() << "Updating name from " << cat->getName() << " to " << it->second.asString() << LL_ENDL; + LL_INFOS(LOG_INV) << "Updating name from " << cat->getName() << " to " << it->second.asString() << LL_ENDL; cat->rename(it->second.asString()); mask |= LLInventoryObserver::LABEL; } else { - LL_ERRS() << "unhandled updates for field: " << it->first << LL_ENDL; + LL_ERRS(LOG_INV) << "unhandled updates for field: " << it->first << LL_ENDL; } } mask |= LLInventoryObserver::INTERNAL; addChangedMask(mask, cat->getUUID()); - gInventory.notifyObservers(); // do we want to be able to make this optional? + notifyObservers(); // do we want to be able to make this optional? } } @@ -1317,8 +1353,8 @@ void LLInventoryModel::onDescendentsPurgedFromServer(const LLUUID& object_id, bo while (deleted_count > 0); if (total_deleted_count != count) { - LL_WARNS() << "Unexpected count of categories deleted, got " - << total_deleted_count << " expected " << count << LL_ENDL; + LL_WARNS(LOG_INV) << "Unexpected count of categories deleted, got " + << total_deleted_count << " expected " << count << LL_ENDL; } //gInventory.validate(); } @@ -1355,15 +1391,15 @@ void LLInventoryModel::onObjectDeletedFromServer(const LLUUID& object_id, bool f // Delete a particular inventory object by ID. void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, bool do_notify_observers) { - LL_DEBUGS() << "LLInventoryModel::deleteObject()" << LL_ENDL; + LL_DEBUGS(LOG_INV) << "LLInventoryModel::deleteObject()" << LL_ENDL; LLPointer<LLInventoryObject> obj = getObject(id); if (!obj) { - LL_WARNS() << "Deleting non-existent object [ id: " << id << " ] " << LL_ENDL; + LL_WARNS(LOG_INV) << "Deleting non-existent object [ id: " << id << " ] " << LL_ENDL; return; } - LL_DEBUGS() << "Deleting inventory object " << id << LL_ENDL; + LL_DEBUGS(LOG_INV) << "Deleting inventory object " << id << LL_ENDL; mLastItem = NULL; LLUUID parent_id = obj->getParentUUID(); mCategoryMap.erase(id); @@ -1386,7 +1422,7 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo { if (item_list->size()) { - LL_WARNS() << "Deleting cat " << id << " while it still has child items" << LL_ENDL; + LL_WARNS(LOG_INV) << "Deleting cat " << id << " while it still has child items" << LL_ENDL; } delete item_list; mParentChildItemTree.erase(id); @@ -1396,7 +1432,7 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo { if (cat_list->size()) { - LL_WARNS() << "Deleting cat " << id << " while it still has child cats" << LL_ENDL; + LL_WARNS(LOG_INV) << "Deleting cat " << id << " while it still has child cats" << LL_ENDL; } delete cat_list; mParentChildCategoryTree.erase(id); @@ -1431,7 +1467,7 @@ void LLInventoryModel::updateLinkedObjectsFromPurge(const LLUUID &baseobj_id) // everything else on the changelist will also get rebuilt. if (item_array.size() > 0) { - gInventory.notifyObservers(); + notifyObservers(); for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin(); iter != item_array.end(); iter++) @@ -1441,7 +1477,7 @@ void LLInventoryModel::updateLinkedObjectsFromPurge(const LLUUID &baseobj_id) if (item_id == baseobj_id) continue; addChangedMask(LLInventoryObserver::REBUILD, item_id); } - gInventory.notifyObservers(); + notifyObservers(); } } @@ -1464,6 +1500,9 @@ BOOL LLInventoryModel::containsObserver(LLInventoryObserver* observer) const void LLInventoryModel::idleNotifyObservers() { + // *FIX: Think I want this conditional or moved elsewhere... + handleResponses(true); + if (mModifyMask == LLInventoryObserver::NONE && (mChangedItemIDs.size() == 0)) { return; @@ -1479,7 +1518,7 @@ void LLInventoryModel::notifyObservers() // Within notifyObservers, something called notifyObservers // again. This type of recursion is unsafe because it causes items to be // processed twice, and this can easily lead to infinite loops. - LL_WARNS() << "Call was made to notifyObservers within notifyObservers!" << LL_ENDL; + LL_WARNS(LOG_INV) << "Call was made to notifyObservers within notifyObservers!" << LL_ENDL; return; } @@ -1509,18 +1548,18 @@ void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent) // Something marked an item for change within a call to notifyObservers // (which is in the process of processing the list of items marked for change). // This means the change may fail to be processed. - LL_WARNS() << "Adding changed mask within notify observers! Change will likely be lost." << LL_ENDL; + LL_WARNS(LOG_INV) << "Adding changed mask within notify observers! Change will likely be lost." << LL_ENDL; LLViewerInventoryItem *item = getItem(referent); if (item) { - LL_WARNS() << "Item " << item->getName() << LL_ENDL; + LL_WARNS(LOG_INV) << "Item " << item->getName() << LL_ENDL; } else { LLViewerInventoryCategory *cat = getCategory(referent); if (cat) { - LL_WARNS() << "Category " << cat->getName() << LL_ENDL; + LL_WARNS(LOG_INV) << "Category " << cat->getName() << LL_ENDL; } } } @@ -1544,91 +1583,18 @@ void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent) } } -// If we get back a normal response, handle it here -void LLInventoryModel::fetchInventoryResponder::httpSuccess() -{ - const LLSD& content = getContent(); - if (!content.isMap()) - { - failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content); - return; - } - start_new_inventory_observer(); - - /*LLUUID agent_id; - agent_id = content["agent_id"].asUUID(); - if(agent_id != gAgent.getID()) - { - LL_WARNS() << "Got a inventory update for the wrong agent: " << agent_id - << LL_ENDL; - return; - }*/ - item_array_t items; - update_map_t update; - S32 count = content["items"].size(); - LLUUID folder_id; - // Does this loop ever execute more than once? - for(S32 i = 0; i < count; ++i) - { - LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem; - titem->unpackMessage(content["items"][i]); - - LL_DEBUGS() << "LLInventoryModel::fetchInventoryResponder item id: " - << titem->getUUID() << LL_ENDL; - items.push_back(titem); - // examine update for changes. - LLViewerInventoryItem* itemp = gInventory.getItem(titem->getUUID()); - if(itemp) - { - if(titem->getParentUUID() == itemp->getParentUUID()) - { - update[titem->getParentUUID()]; - } - else - { - ++update[titem->getParentUUID()]; - --update[itemp->getParentUUID()]; - } - } - else - { - ++update[titem->getParentUUID()]; - } - if (folder_id.isNull()) - { - folder_id = titem->getParentUUID(); - } - } - - U32 changes = 0x0; - //as above, this loop never seems to loop more than once per call - for (item_array_t::iterator it = items.begin(); it != items.end(); ++it) - { - changes |= gInventory.updateItem(*it); - } - gInventory.notifyObservers(); - gViewerWindow->getWindow()->decBusyCount(); -} - -//If we get back an error (not found, etc...), handle it here -void LLInventoryModel::fetchInventoryResponder::httpFailure() -{ - LL_WARNS() << dumpResponse() << LL_ENDL; - gInventory.notifyObservers(); -} - bool LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id) const { if(folder_id.isNull()) { - LL_WARNS() << "Calling fetch descendents on NULL folder id!" << LL_ENDL; + LL_WARNS(LOG_INV) << "Calling fetch descendents on NULL folder id!" << LL_ENDL; return false; } LLViewerInventoryCategory* cat = getCategory(folder_id); if(!cat) { - LL_WARNS() << "Asked to fetch descendents of non-existent folder: " - << folder_id << LL_ENDL; + LL_WARNS(LOG_INV) << "Asked to fetch descendents of non-existent folder: " + << folder_id << LL_ENDL; return false; } //S32 known_descendents = 0; @@ -1649,8 +1615,8 @@ void LLInventoryModel::cache( const LLUUID& parent_folder_id, const LLUUID& agent_id) { - LL_DEBUGS() << "Caching " << parent_folder_id << " for " << agent_id - << LL_ENDL; + LL_DEBUGS(LOG_INV) << "Caching " << parent_folder_id << " for " << agent_id + << LL_ENDL; LLViewerInventoryCategory* root_cat = getCategory(parent_folder_id); if(!root_cat) return; cat_array_t categories; @@ -1675,19 +1641,19 @@ void LLInventoryModel::cache( gzip_filename.append(".gz"); if(gzip_file(inventory_filename, gzip_filename)) { - LL_DEBUGS() << "Successfully compressed " << inventory_filename << LL_ENDL; + LL_DEBUGS(LOG_INV) << "Successfully compressed " << inventory_filename << LL_ENDL; LLFile::remove(inventory_filename); } else { - LL_WARNS() << "Unable to compress " << inventory_filename << LL_ENDL; + LL_WARNS(LOG_INV) << "Unable to compress " << inventory_filename << LL_ENDL; } } void LLInventoryModel::addCategory(LLViewerInventoryCategory* category) { - //LL_INFOS() << "LLInventoryModel::addCategory()" << LL_ENDL; + //LL_INFOS(LOG_INV) << "LLInventoryModel::addCategory()" << LL_ENDL; if(category) { // We aren't displaying the Meshes folder @@ -1757,7 +1723,9 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item) if ((item->getType() == LLAssetType::AT_NONE) || LLAssetType::lookup(item->getType()) == LLAssetType::badLookup()) { - LL_WARNS() << "Got bad asset type for item [ name: " << item->getName() << " type: " << item->getType() << " inv-type: " << item->getInventoryType() << " ], ignoring." << LL_ENDL; + LL_WARNS(LOG_INV) << "Got bad asset type for item [ name: " << item->getName() + << " type: " << item->getType() + << " inv-type: " << item->getInventoryType() << " ], ignoring." << LL_ENDL; return; } @@ -1765,7 +1733,9 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item) // The item will show up as a broken link. if (item->getIsBrokenLink()) { - LL_INFOS() << "Adding broken link [ name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) parent: " << item->getParentUUID() << LL_ENDL; + LL_INFOS(LOG_INV) << "Adding broken link [ name: " << item->getName() + << " itemID: " << item->getUUID() + << " assetID: " << item->getAssetUUID() << " ) parent: " << item->getParentUUID() << LL_ENDL; } if (item->getIsLinkType()) { @@ -1781,7 +1751,7 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item) // Empty the entire contents void LLInventoryModel::empty() { -// LL_INFOS() << "LLInventoryModel::empty()" << LL_ENDL; +// LL_INFOS(LOG_INV) << "LLInventoryModel::empty()" << LL_ENDL; std::for_each( mParentChildCategoryTree.begin(), mParentChildCategoryTree.end(), @@ -1814,29 +1784,29 @@ void LLInventoryModel::accountForUpdate(const LLCategoryUpdate& update) const descendents_actual += update.mDescendentDelta; cat->setDescendentCount(descendents_actual); cat->setVersion(++version); - LL_DEBUGS("Inventory") << "accounted: '" << cat->getName() << "' " - << version << " with " << descendents_actual - << " descendents." << LL_ENDL; + LL_DEBUGS(LOG_INV) << "accounted: '" << cat->getName() << "' " + << version << " with " << descendents_actual + << " descendents." << LL_ENDL; } else { // Error condition, this means that the category did not register that // it got new descendents (perhaps because it is still being loaded) // which means its descendent count will be wrong. - LL_WARNS() << "Accounting failed for '" << cat->getName() << "' version:" - << version << " due to mismatched descendent count: server == " - << descendents_server << ", viewer == " << descendents_actual << LL_ENDL; + LL_WARNS(LOG_INV) << "Accounting failed for '" << cat->getName() << "' version:" + << version << " due to mismatched descendent count: server == " + << descendents_server << ", viewer == " << descendents_actual << LL_ENDL; } } else { - LL_WARNS() << "Accounting failed for '" << cat->getName() << "' version: unknown (" - << version << ")" << LL_ENDL; + LL_WARNS(LOG_INV) << "Accounting failed for '" << cat->getName() << "' version: unknown (" + << version << ")" << LL_ENDL; } } else { - LL_WARNS() << "No category found for update " << update.mCategoryID << LL_ENDL; + LL_WARNS(LOG_INV) << "No category found for update " << update.mCategoryID << LL_ENDL; } } @@ -1918,7 +1888,7 @@ bool LLInventoryModel::loadSkeleton( const LLSD& options, const LLUUID& owner_id) { - LL_DEBUGS() << "importing inventory skeleton for " << owner_id << LL_ENDL; + LL_DEBUGS(LOG_INV) << "importing inventory skeleton for " << owner_id << LL_ENDL; typedef std::set<LLPointer<LLViewerInventoryCategory>, InventoryIDPtrLess> cat_set_t; cat_set_t temp_cats; @@ -1955,7 +1925,7 @@ bool LLInventoryModel::loadSkeleton( } else { - LL_WARNS() << "Unable to import near " << name.asString() << LL_ENDL; + LL_WARNS(LOG_INV) << "Unable to import near " << name.asString() << LL_ENDL; rv = false; } } @@ -1992,7 +1962,7 @@ bool LLInventoryModel::loadSkeleton( } else { - LL_INFOS() << "Unable to gunzip " << gzip_filename << LL_ENDL; + LL_INFOS(LOG_INV) << "Unable to gunzip " << gzip_filename << LL_ENDL; } } bool is_cache_obsolete = false; @@ -2073,10 +2043,10 @@ bool LLInventoryModel::loadSkeleton( if (item->getIsBrokenLink()) { //bad_link_count++; - LL_DEBUGS() << "Attempted to add cached link item without baseobj present ( name: " - << item->getName() << " itemID: " << item->getUUID() - << " assetID: " << item->getAssetUUID() - << " ). Ignoring and invalidating " << cat->getName() << " . " << LL_ENDL; + LL_DEBUGS(LOG_INV) << "Attempted to add cached link item without baseobj present ( name: " + << item->getName() << " itemID: " << item->getUUID() + << " assetID: " << item->getAssetUUID() + << " ). Ignoring and invalidating " << cat->getName() << " . " << LL_ENDL; possible_broken_links.push_back(item); continue; } @@ -2103,7 +2073,7 @@ bool LLInventoryModel::loadSkeleton( { bad_link_count++; invalid_categories.insert(cit->second); - //LL_INFOS() << "link still broken: " << item->getName() << " in folder " << cat->getName() << LL_ENDL; + //LL_INFOS(LOG_INV) << "link still broken: " << item->getName() << " in folder " << cat->getName() << LL_ENDL; } else { @@ -2115,11 +2085,11 @@ bool LLInventoryModel::loadSkeleton( } } - LL_INFOS() << "Attempted to add " << bad_link_count - << " cached link items without baseobj present. " - << good_link_count << " link items were successfully added. " - << recovered_link_count << " links added in recovery. " - << "The corresponding categories were invalidated." << LL_ENDL; + LL_INFOS(LOG_INV) << "Attempted to add " << bad_link_count + << " cached link items without baseobj present. " + << good_link_count << " link items were successfully added. " + << recovered_link_count << " links added in recovery. " + << "The corresponding categories were invalidated." << LL_ENDL; } } @@ -2143,9 +2113,9 @@ bool LLInventoryModel::loadSkeleton( { LLViewerInventoryCategory* cat = (*invalid_cat_it).get(); cat->setVersion(NO_VERSION); - LL_DEBUGS("Inventory") << "Invalidating category name: " << cat->getName() << " UUID: " << cat->getUUID() << " due to invalid descendents cache" << LL_ENDL; + LL_DEBUGS(LOG_INV) << "Invalidating category name: " << cat->getName() << " UUID: " << cat->getUUID() << " due to invalid descendents cache" << LL_ENDL; } - LL_INFOS("Inventory") << "Invalidated " << invalid_categories.size() << " categories due to invalid descendents cache" << LL_ENDL; + LL_INFOS(LOG_INV) << "Invalidated " << invalid_categories.size() << " categories due to invalid descendents cache" << LL_ENDL; // At this point, we need to set the known descendents for each // category which successfully cached so that we do not @@ -2177,15 +2147,15 @@ bool LLInventoryModel::loadSkeleton( if(is_cache_obsolete) { // If out of date, remove the gzipped file too. - LL_WARNS() << "Inv cache out of date, removing" << LL_ENDL; + LL_WARNS(LOG_INV) << "Inv cache out of date, removing" << LL_ENDL; LLFile::remove(gzip_filename); } categories.clear(); // will unref and delete entries } - LL_INFOS() << "Successfully loaded " << cached_category_count - << " categories and " << cached_item_count << " items from cache." - << LL_ENDL; + LL_INFOS(LOG_INV) << "Successfully loaded " << cached_category_count + << " categories and " << cached_item_count << " items from cache." + << LL_ENDL; return rv; } @@ -2195,7 +2165,7 @@ bool LLInventoryModel::loadSkeleton( // should be sufficient for our needs. void LLInventoryModel::buildParentChildMap() { - LL_INFOS() << "LLInventoryModel::buildParentChildMap()" << LL_ENDL; + LL_INFOS(LOG_INV) << "LLInventoryModel::buildParentChildMap()" << LL_ENDL; // *NOTE: I am skipping the logic around folder version // synchronization here because it seems if a folder is lost, we @@ -2264,15 +2234,15 @@ void LLInventoryModel::buildParentChildMap() // implement it, we would need a set or map of uuid pairs // which would be (folder_id, new_parent_id) to be sent up // to the server. - LL_INFOS() << "Lost category: " << cat->getUUID() << " - " - << cat->getName() << LL_ENDL; + LL_INFOS(LOG_INV) << "Lost category: " << cat->getUUID() << " - " + << cat->getName() << LL_ENDL; ++lost; lost_cats.push_back(cat); } } if(lost) { - LL_WARNS() << "Found " << lost << " lost categories." << LL_ENDL; + LL_WARNS(LOG_INV) << "Found " << lost << " lost categories." << LL_ENDL; } // Do moves in a separate pass to make sure we've properly filed @@ -2307,7 +2277,7 @@ void LLInventoryModel::buildParentChildMap() } else { - LL_WARNS() << "Lost and found Not there!!" << LL_ENDL; + LL_WARNS(LOG_INV) << "Lost and found Not there!!" << LL_ENDL; } } @@ -2342,8 +2312,8 @@ void LLInventoryModel::buildParentChildMap() } else { - LL_INFOS() << "Lost item: " << item->getUUID() << " - " - << item->getName() << LL_ENDL; + LL_INFOS(LOG_INV) << "Lost item: " << item->getUUID() << " - " + << item->getName() << LL_ENDL; ++lost; // plop it into the lost & found. // @@ -2359,13 +2329,13 @@ void LLInventoryModel::buildParentChildMap() } else { - LL_WARNS() << "Lost and found Not there!!" << LL_ENDL; + LL_WARNS(LOG_INV) << "Lost and found Not there!!" << LL_ENDL; } } } if(lost) { - LL_WARNS() << "Found " << lost << " lost items." << LL_ENDL; + LL_WARNS(LOG_INV) << "Found " << lost << " lost items." << LL_ENDL; LLMessageSystem* msg = gMessageSystem; BOOL start_new_message = TRUE; const LLUUID lnf = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); @@ -2443,10 +2413,85 @@ void LLInventoryModel::buildParentChildMap() if (!gInventory.validate()) { - LL_WARNS() << "model failed validity check!" << LL_ENDL; + LL_WARNS(LOG_INV) << "model failed validity check!" << LL_ENDL; + } +} + +// Would normally do this at construction but that's too early +// in the process for gInventory. Have the first requestPost() +// call set things up. +void LLInventoryModel::initHttpRequest() +{ + if (! mHttpRequestFG) + { + // Haven't initialized, get to it + LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp()); + + mHttpRequestFG = new LLCore::HttpRequest; + mHttpRequestBG = new LLCore::HttpRequest; + mHttpOptions = new LLCore::HttpOptions; + mHttpOptions->setTransferTimeout(300); + mHttpOptions->setUseRetryAfter(true); + // mHttpOptions->setTrace(2); // Do tracing of requests + mHttpHeaders = new LLCore::HttpHeaders; + mHttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML); + mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_LLSD_XML); + mHttpPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_INVENTORY); } } +void LLInventoryModel::handleResponses(bool foreground) +{ + if (foreground) + { + mHttpRequestFG->update(0); + } + else + { + mHttpRequestBG->update(50000L); + } +} + +LLCore::HttpHandle LLInventoryModel::requestPost(bool foreground, + const std::string & url, + const LLSD & body, + LLCore::HttpHandler * handler, + const char * const message) +{ + if (! mHttpRequestFG) + { + // We do the initialization late and lazily as this class is + // statically-constructed and not all the bits are ready at + // that time. + initHttpRequest(); + } + + LLCore::HttpRequest * request(foreground ? mHttpRequestFG : mHttpRequestBG); + LLCore::HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); + LLCore::BufferArray * ba = new LLCore::BufferArray; + LLCore::BufferArrayStream bas(ba); + LLSDSerialize::toXML(body, bas); + + handle = request->requestPost(mHttpPolicyClass, + (foreground ? mHttpPriorityFG : mHttpPriorityBG), + url, + ba, + mHttpOptions, + mHttpHeaders, + handler); + ba->release(); + if (LLCORE_HTTP_HANDLE_INVALID == handle) + { + LLCore::HttpStatus status(request->getStatus()); + LL_WARNS(LOG_INV) << "HTTP POST request failed for " << message + << ", Status: " << status.toTerseString() + << " Reason: '" << status.toString() << "'" + << LL_ENDL; + delete handler; + } + return handle; +} + void LLInventoryModel::createCommonSystemCategories() { gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH,true); @@ -2495,14 +2540,14 @@ bool LLInventoryModel::loadFromFile(const std::string& filename, { if(filename.empty()) { - LL_ERRS() << "Filename is Null!" << LL_ENDL; + LL_ERRS(LOG_INV) << "Filename is Null!" << LL_ENDL; return false; } - LL_INFOS() << "LLInventoryModel::loadFromFile(" << filename << ")" << LL_ENDL; + LL_INFOS(LOG_INV) << "LLInventoryModel::loadFromFile(" << filename << ")" << LL_ENDL; LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/ if(!file) { - LL_INFOS() << "unable to load inventory from: " << filename << LL_ENDL; + LL_INFOS(LOG_INV) << "unable to load inventory from: " << filename << LL_ENDL; return false; } // *NOTE: This buffer size is hard coded into scanf() below. @@ -2541,7 +2586,7 @@ bool LLInventoryModel::loadFromFile(const std::string& filename, } else { - LL_WARNS() << "loadInventoryFromFile(). Ignoring invalid inventory category: " << inv_cat->getName() << LL_ENDL; + LL_WARNS(LOG_INV) << "loadInventoryFromFile(). Ignoring invalid inventory category: " << inv_cat->getName() << LL_ENDL; //delete inv_cat; // automatic when inv_cat is reassigned or destroyed } } @@ -2559,8 +2604,8 @@ bool LLInventoryModel::loadFromFile(const std::string& filename, if(inv_item->getUUID().isNull()) { //delete inv_item; // automatic when inv_cat is reassigned or destroyed - LL_WARNS() << "Ignoring inventory with null item id: " - << inv_item->getName() << LL_ENDL; + LL_WARNS(LOG_INV) << "Ignoring inventory with null item id: " + << inv_item->getName() << LL_ENDL; } else @@ -2570,14 +2615,14 @@ bool LLInventoryModel::loadFromFile(const std::string& filename, } else { - LL_WARNS() << "loadInventoryFromFile(). Ignoring invalid inventory item: " << inv_item->getName() << LL_ENDL; + LL_WARNS(LOG_INV) << "loadInventoryFromFile(). Ignoring invalid inventory item: " << inv_item->getName() << LL_ENDL; //delete inv_item; // automatic when inv_cat is reassigned or destroyed } } else { - LL_WARNS() << "Unknown token in inventory file '" << keyword << "'" - << LL_ENDL; + LL_WARNS(LOG_INV) << "Unknown token in inventory file '" << keyword << "'" + << LL_ENDL; } } fclose(file); @@ -2593,14 +2638,14 @@ bool LLInventoryModel::saveToFile(const std::string& filename, { if(filename.empty()) { - LL_ERRS() << "Filename is Null!" << LL_ENDL; + LL_ERRS(LOG_INV) << "Filename is Null!" << LL_ENDL; return false; } - LL_INFOS() << "LLInventoryModel::saveToFile(" << filename << ")" << LL_ENDL; + LL_INFOS(LOG_INV) << "LLInventoryModel::saveToFile(" << filename << ")" << LL_ENDL; LLFILE* file = LLFile::fopen(filename, "wb"); /*Flawfinder: ignore*/ if(!file) { - LL_WARNS() << "unable to save inventory to: " << filename << LL_ENDL; + LL_WARNS(LOG_INV) << "unable to save inventory to: " << filename << LL_ENDL; return false; } @@ -2705,8 +2750,8 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); if(agent_id != gAgent.getID()) { - LL_WARNS() << "Got a inventory update for the wrong agent: " << agent_id - << LL_ENDL; + LL_WARNS(LOG_INV) << "Got a inventory update for the wrong agent: " << agent_id + << LL_ENDL; return false; } item_array_t items; @@ -2718,8 +2763,8 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32 { LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem; titem->unpackMessage(msg, _PREHASH_InventoryData, i); - LL_DEBUGS() << "LLInventoryModel::messageUpdateCore() item id:" - << titem->getUUID() << LL_ENDL; + LL_DEBUGS(LOG_INV) << "LLInventoryModel::messageUpdateCore() item id: " + << titem->getUUID() << LL_ENDL; items.push_back(titem); // examine update for changes. LLViewerInventoryItem* itemp = gInventory.getItem(titem->getUUID()); @@ -2770,17 +2815,17 @@ void LLInventoryModel::removeInventoryItem(LLUUID agent_id, LLMessageSystem* msg { LLUUID item_id; S32 count = msg->getNumberOfBlocksFast(msg_label); - LL_DEBUGS() << "Message has " << count << " item blocks" << LL_ENDL; + LL_DEBUGS(LOG_INV) << "Message has " << count << " item blocks" << LL_ENDL; uuid_vec_t item_ids; update_map_t update; for(S32 i = 0; i < count; ++i) { msg->getUUIDFast(msg_label, _PREHASH_ItemID, item_id, i); - LL_DEBUGS() << "Checking for item-to-be-removed " << item_id << LL_ENDL; + LL_DEBUGS(LOG_INV) << "Checking for item-to-be-removed " << item_id << LL_ENDL; LLViewerInventoryItem* itemp = gInventory.getItem(item_id); if(itemp) { - LL_DEBUGS() << "Item will be removed " << item_id << LL_ENDL; + LL_DEBUGS(LOG_INV) << "Item will be removed " << item_id << LL_ENDL; // we only bother with the delete and account if we found // the item - this is usually a back-up for permissions, // so frequently the item will already be gone. @@ -2791,7 +2836,7 @@ void LLInventoryModel::removeInventoryItem(LLUUID agent_id, LLMessageSystem* msg gInventory.accountForUpdate(update); for(uuid_vec_t::iterator it = item_ids.begin(); it != item_ids.end(); ++it) { - LL_DEBUGS() << "Calling deleteObject " << *it << LL_ENDL; + LL_DEBUGS(LOG_INV) << "Calling deleteObject " << *it << LL_ENDL; gInventory.deleteObject(*it); } } @@ -2799,13 +2844,13 @@ void LLInventoryModel::removeInventoryItem(LLUUID agent_id, LLMessageSystem* msg // static void LLInventoryModel::processRemoveInventoryItem(LLMessageSystem* msg, void**) { - LL_DEBUGS() << "LLInventoryModel::processRemoveInventoryItem()" << LL_ENDL; + LL_DEBUGS(LOG_INV) << "LLInventoryModel::processRemoveInventoryItem()" << LL_ENDL; LLUUID agent_id, item_id; msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); if(agent_id != gAgent.getID()) { - LL_WARNS() << "Got a RemoveInventoryItem for the wrong agent." - << LL_ENDL; + LL_WARNS(LOG_INV) << "Got a RemoveInventoryItem for the wrong agent." + << LL_ENDL; return; } LLInventoryModel::removeInventoryItem(agent_id, msg, _PREHASH_InventoryData); @@ -2816,14 +2861,14 @@ void LLInventoryModel::processRemoveInventoryItem(LLMessageSystem* msg, void**) void LLInventoryModel::processUpdateInventoryFolder(LLMessageSystem* msg, void**) { - LL_DEBUGS() << "LLInventoryModel::processUpdateInventoryFolder()" << LL_ENDL; + LL_DEBUGS(LOG_INV) << "LLInventoryModel::processUpdateInventoryFolder()" << LL_ENDL; LLUUID agent_id, folder_id, parent_id; //char name[DB_INV_ITEM_NAME_BUF_SIZE]; msg->getUUIDFast(_PREHASH_FolderData, _PREHASH_AgentID, agent_id); if(agent_id != gAgent.getID()) { - LL_WARNS() << "Got an UpdateInventoryFolder for the wrong agent." - << LL_ENDL; + LL_WARNS(LOG_INV) << "Got an UpdateInventoryFolder for the wrong agent." + << LL_ENDL; return; } LLPointer<LLViewerInventoryCategory> lastfolder; // hack @@ -3881,7 +3926,7 @@ bool LLInventoryModel::validate() const ///---------------------------------------------------------------------------- -/* +#if 0 BOOL decompress_file(const char* src_filename, const char* dst_filename) { BOOL rv = FALSE; @@ -3920,4 +3965,140 @@ BOOL decompress_file(const char* src_filename, const char* dst_filename) if(dst != NULL) fclose(dst); return rv; } -*/ +#endif + +// ==== FetchItemHttpHandler ==== + +LLInventoryModel::FetchItemHttpHandler::FetchItemHttpHandler(const LLSD & request_sd) + : LLCore::HttpHandler(), + mRequestSD(request_sd) +{} + +LLInventoryModel::FetchItemHttpHandler::~FetchItemHttpHandler() +{} + +void LLInventoryModel::FetchItemHttpHandler::onCompleted(LLCore::HttpHandle handle, + LLCore::HttpResponse * response) +{ + LLCore::HttpStatus status(response->getStatus()); + if (! status) + { + processFailure(status, response); + } + else + { + LLCore::BufferArray * body(response->getBody()); + if (! body || ! body->size()) + { + LL_WARNS(LOG_INV) << "Missing data in inventory item query." << LL_ENDL; + processFailure("HTTP response for inventory item query missing body", response); + goto only_exit; + } + + LLCore::BufferArrayStream bas(body); + LLSD body_llsd; + S32 parse_status(LLSDSerialize::fromXML(body_llsd, bas)); + if (LLSDParser::PARSE_FAILURE == parse_status) + { + // INFOS-level logging will occur on the parsed failure + processFailure("HTTP response for inventory item query has malformed LLSD", response); + goto only_exit; + } + + // Okay, process data if possible + processData(body_llsd, response); + } + +only_exit: + // Must delete on completion. + delete this; +} + +void LLInventoryModel::FetchItemHttpHandler::processData(LLSD & content, LLCore::HttpResponse * response) +{ + if (! content.isMap()) + { + processFailure("LLSD response for inventory item not a map", response); + return; + } + + start_new_inventory_observer(); + +#if 0 + LLUUID agent_id; + agent_id = content["agent_id"].asUUID(); + if (agent_id != gAgent.getID()) + { + LL_WARNS(LOG_INV) << "Got a inventory update for the wrong agent: " << agent_id + << LL_ENDL; + return; + } +#endif + + LLInventoryModel::item_array_t items; + LLInventoryModel::update_map_t update; + LLUUID folder_id; + LLSD content_items(content["items"]); + const S32 count(content_items.size()); + + // Does this loop ever execute more than once? + for (S32 i(0); i < count; ++i) + { + LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem; + titem->unpackMessage(content_items[i]); + + LL_DEBUGS(LOG_INV) << "ItemHttpHandler::httpSuccess item id: " + << titem->getUUID() << LL_ENDL; + items.push_back(titem); + + // examine update for changes. + LLViewerInventoryItem * itemp(gInventory.getItem(titem->getUUID())); + + if (itemp) + { + if (titem->getParentUUID() == itemp->getParentUUID()) + { + update[titem->getParentUUID()]; + } + else + { + ++update[titem->getParentUUID()]; + --update[itemp->getParentUUID()]; + } + } + else + { + ++update[titem->getParentUUID()]; + } + + if (folder_id.isNull()) + { + folder_id = titem->getParentUUID(); + } + } + + // as above, this loop never seems to loop more than once per call + U32 changes(0U); + for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it) + { + changes |= gInventory.updateItem(*it); + } + // *HUH: Have computed changes, nothing uses it. + + gInventory.notifyObservers(); + gViewerWindow->getWindow()->decBusyCount(); +} + + +void LLInventoryModel::FetchItemHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::HttpResponse * response) +{ + LL_WARNS(LOG_INV) << dumpResponse() << LL_ENDL; + gInventory.notifyObservers(); +} + +void LLInventoryModel::FetchItemHttpHandler::processFailure(const char * const reason, LLCore::HttpResponse * response) +{ + LL_WARNS(LOG_INV) << dumpResponse() << LL_ENDL; + gInventory.notifyObservers(); +} + diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 2e957809be..ac336e347c 100755 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -27,6 +27,11 @@ #ifndef LL_LLINVENTORYMODEL_H #define LL_LLINVENTORYMODEL_H +#include <map> +#include <set> +#include <string> +#include <vector> + #include "llassettype.h" #include "llfoldertype.h" #include "llframetimer.h" @@ -36,10 +41,11 @@ #include "llviewerinventory.h" #include "llstring.h" #include "llmd5.h" -#include <map> -#include <set> -#include <string> -#include <vector> +#include "httpcommon.h" +#include "httprequest.h" +#include "httpoptions.h" +#include "httpheaders.h" +#include "httphandler.h" class LLInventoryObserver; class LLInventoryObject; @@ -60,9 +66,8 @@ class LLInventoryCollectFunctor; class LLInventoryModel { LOG_CLASS(LLInventoryModel); -public: - friend class LLInventoryModelFetchDescendentsResponder; +public: enum EHasChildren { CHILDREN_NO, @@ -74,14 +79,31 @@ public: typedef std::vector<LLPointer<LLViewerInventoryItem> > item_array_t; typedef std::set<LLUUID> changed_items_t; - class fetchInventoryResponder : public LLCurl::Responder + // HTTP handler for individual item requests (inventory or library). + // Background item requests are derived from this in the background + // inventory system. All folder requests are also located there + // but have their own handler derived from HttpHandler. + class FetchItemHttpHandler : public LLCore::HttpHandler { - LOG_CLASS(fetchInventoryResponder); public: - fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {}; + LOG_CLASS(FetchItemHttpHandler); + + FetchItemHttpHandler(const LLSD & request_sd); + virtual ~FetchItemHttpHandler(); + protected: - virtual void httpSuccess(); - virtual void httpFailure(); + FetchItemHttpHandler(const FetchItemHttpHandler &); // Not defined + void operator=(const FetchItemHttpHandler &); // Not defined + + public: + virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response); + + private: + void processData(LLSD & body, LLCore::HttpResponse * response); + void processFailure(LLCore::HttpStatus status, LLCore::HttpResponse * response); + void processFailure(const char * const reason, LLCore::HttpResponse * response); + + private: LLSD mRequestSD; }; @@ -109,6 +131,9 @@ public: private: bool mIsAgentInvUsable; // used to handle an invalid inventory state + // One-time initialization of HTTP system. + void initHttpRequest(); + //-------------------------------------------------------------------- // Root Folders //-------------------------------------------------------------------- @@ -520,6 +545,41 @@ private: /******************************************************************************** ** ** + ** HTTP Transport + **/ +public: + // Invoke handler completion method (onCompleted) for all + // requests that are ready. + void handleResponses(bool foreground); + + // Request an inventory HTTP operation to either the + // foreground or background processor. These are actually + // the same service queue but the background requests are + // seviced more slowly effectively de-prioritizing new + // requests. + LLCore::HttpHandle requestPost(bool foreground, + const std::string & url, + const LLSD & body, + LLCore::HttpHandler * handler, + const char * const message); + +private: + // Usual plumbing for LLCore:: HTTP operations. + LLCore::HttpRequest * mHttpRequestFG; + LLCore::HttpRequest * mHttpRequestBG; + LLCore::HttpOptions * mHttpOptions; + LLCore::HttpHeaders * mHttpHeaders; + LLCore::HttpRequest::policy_t mHttpPolicyClass; + LLCore::HttpRequest::priority_t mHttpPriorityFG; + LLCore::HttpRequest::priority_t mHttpPriorityBG; + +/** HTTP Transport + ** ** + *******************************************************************************/ + + +/******************************************************************************** + ** ** ** MISCELLANEOUS **/ diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 2de37b0790..443c54df42 100755 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2014, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -37,31 +37,113 @@ #include "llviewermessage.h" #include "llviewerregion.h" #include "llviewerwindow.h" +#include "llhttpconstants.h" +#include "bufferarray.h" +#include "bufferstream.h" +#include "llsdserialize.h" + +namespace +{ + +// Http request handler class for single inventory item requests. +// +// We'll use a handler-per-request pattern here rather than +// a shared handler. Mainly convenient as this was converted +// from a Responder class model. +// +class BGItemHttpHandler : public LLInventoryModel::FetchItemHttpHandler +{ + LOG_CLASS(BGItemHttpHandler); + +public: + BGItemHttpHandler(const LLSD & request_sd) + : LLInventoryModel::FetchItemHttpHandler(request_sd) + { + LLInventoryModelBackgroundFetch::instance().incrFetchCount(1); + } + + virtual ~BGItemHttpHandler() + { + LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); + } + +protected: + BGItemHttpHandler(const BGItemHttpHandler &); // Not defined + void operator=(const BGItemHttpHandler &); // Not defined +}; + + +// Http request handler class for folders. +class BGFolderHttpHandler : public LLCore::HttpHandler +{ + LOG_CLASS(BGFolderHttpHandler); + +public: + BGFolderHttpHandler(const LLSD & request_sd, const uuid_vec_t & recursive_cats) + : LLCore::HttpHandler(), + mRequestSD(request_sd), + mRecursiveCatUUIDs(recursive_cats) + { + LLInventoryModelBackgroundFetch::instance().incrFetchCount(1); + } + + virtual ~BGFolderHttpHandler() + { + LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); + } + +protected: + BGFolderHttpHandler(const BGFolderHttpHandler &); // Not defined + void operator=(const BGFolderHttpHandler &); // Not defined + +public: + virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response); + + bool getIsRecursive(const LLUUID & cat_id) const; + +private: + void processData(LLSD & body, LLCore::HttpResponse * response); + void processFailure(LLCore::HttpStatus status, LLCore::HttpResponse * response); + void processFailure(const char * const reason, LLCore::HttpResponse * response); + +private: + LLSD mRequestSD; + const uuid_vec_t mRecursiveCatUUIDs; // hack for storing away which cat fetches are recursive +}; + -const F32 MAX_TIME_FOR_SINGLE_FETCH = 10.f; const S32 MAX_FETCH_RETRIES = 10; -LLInventoryModelBackgroundFetch::LLInventoryModelBackgroundFetch() : +const char * const LOG_INV("Inventory"); + +std::string dumpResponse() +{ + return std::string("ADD SOMETHING MEANINGFUL HERE"); +} + + +} // end of namespace anonymous + + +LLInventoryModelBackgroundFetch::LLInventoryModelBackgroundFetch(): mBackgroundFetchActive(FALSE), mFolderFetchActive(false), + mFetchCount(0), mAllFoldersFetched(FALSE), mRecursiveInventoryFetchStarted(FALSE), mRecursiveLibraryFetchStarted(FALSE), mNumFetchRetries(0), mMinTimeBetweenFetches(0.3f), mMaxTimeBetweenFetches(10.f), - mTimelyFetchPending(FALSE), - mFetchCount(0) -{ -} + mTimelyFetchPending(FALSE) +{} LLInventoryModelBackgroundFetch::~LLInventoryModelBackgroundFetch() -{ -} +{} bool LLInventoryModelBackgroundFetch::isBulkFetchProcessingComplete() const { - return mFetchQueue.empty() && mFetchCount<=0; + return mFetchQueue.empty() && mFetchCount <= 0; } bool LLInventoryModelBackgroundFetch::libraryFetchStarted() const @@ -91,7 +173,7 @@ bool LLInventoryModelBackgroundFetch::inventoryFetchCompleted() const bool LLInventoryModelBackgroundFetch::inventoryFetchInProgress() const { - return inventoryFetchStarted() && !inventoryFetchCompleted(); + return inventoryFetchStarted() && ! inventoryFetchCompleted(); } bool LLInventoryModelBackgroundFetch::isEverythingFetched() const @@ -104,24 +186,36 @@ BOOL LLInventoryModelBackgroundFetch::folderFetchActive() const return mFolderFetchActive; } +void LLInventoryModelBackgroundFetch::addRequestAtFront(const LLUUID & id, BOOL recursive, bool is_category) +{ + mFetchQueue.push_front(FetchQueueInfo(id, recursive, is_category)); +} + +void LLInventoryModelBackgroundFetch::addRequestAtBack(const LLUUID & id, BOOL recursive, bool is_category) +{ + mFetchQueue.push_back(FetchQueueInfo(id, recursive, is_category)); +} + void LLInventoryModelBackgroundFetch::start(const LLUUID& id, BOOL recursive) { - LLViewerInventoryCategory* cat = gInventory.getCategory(id); - if (cat || (id.isNull() && !isEverythingFetched())) - { // it's a folder, do a bulk fetch - LL_DEBUGS("InventoryFetch") << "Start fetching category: " << id << ", recursive: " << recursive << LL_ENDL; + LLViewerInventoryCategory * cat(gInventory.getCategory(id)); + + if (cat || (id.isNull() && ! isEverythingFetched())) + { + // it's a folder, do a bulk fetch + LL_DEBUGS(LOG_INV) << "Start fetching category: " << id << ", recursive: " << recursive << LL_ENDL; mBackgroundFetchActive = TRUE; mFolderFetchActive = true; if (id.isNull()) { - if (!mRecursiveInventoryFetchStarted) + if (! mRecursiveInventoryFetchStarted) { mRecursiveInventoryFetchStarted |= recursive; mFetchQueue.push_back(FetchQueueInfo(gInventory.getRootFolderID(), recursive)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } - if (!mRecursiveLibraryFetchStarted) + if (! mRecursiveLibraryFetchStarted) { mRecursiveLibraryFetchStarted |= recursive; mFetchQueue.push_back(FetchQueueInfo(gInventory.getLibraryRootFolderID(), recursive)); @@ -146,9 +240,9 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, BOOL recursive) } } } - else if (LLViewerInventoryItem* itemp = gInventory.getItem(id)) + else if (LLViewerInventoryItem * itemp = gInventory.getItem(id)) { - if (!itemp->mIsComplete && (mFetchQueue.empty() || mFetchQueue.front().mUUID != id)) + if (! itemp->mIsComplete && (mFetchQueue.empty() || mFetchQueue.front().mUUID != id)) { mBackgroundFetchActive = TRUE; @@ -172,7 +266,7 @@ void LLInventoryModelBackgroundFetch::setAllFoldersFetched() mRecursiveLibraryFetchStarted) { mAllFoldersFetched = TRUE; - //LL_INFOS() << "All folders fetched, validating" << LL_ENDL; + //LL_INFOS(LOG_INV) << "All folders fetched, validating" << LL_ENDL; //gInventory.validate(); } mFolderFetchActive = false; @@ -203,7 +297,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() // No more categories to fetch, stop fetch process. if (mFetchQueue.empty()) { - LL_INFOS() << "Inventory fetch completed" << LL_ENDL; + LL_INFOS(LOG_INV) << "Inventory fetch completed" << LL_ENDL; setAllFoldersFetched(); mBackgroundFetchActive = false; @@ -219,7 +313,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() // Double timeouts on failure. mMinTimeBetweenFetches = llmin(mMinTimeBetweenFetches * 2.f, 10.f); mMaxTimeBetweenFetches = llmin(mMaxTimeBetweenFetches * 2.f, 120.f); - LL_DEBUGS() << "Inventory fetch times grown to (" << mMinTimeBetweenFetches << ", " << mMaxTimeBetweenFetches << ")" << LL_ENDL; + LL_DEBUGS(LOG_INV) << "Inventory fetch times grown to (" << mMinTimeBetweenFetches << ", " << mMaxTimeBetweenFetches << ")" << LL_ENDL; // fetch is no longer considered "timely" although we will wait for full time-out. mTimelyFetchPending = FALSE; } @@ -231,7 +325,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() break; } - if(gDisconnected) + if (gDisconnected) { // Just bail if we are disconnected. break; @@ -292,7 +386,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() // Shrink timeouts based on success. mMinTimeBetweenFetches = llmax(mMinTimeBetweenFetches * 0.8f, 0.3f); mMaxTimeBetweenFetches = llmax(mMaxTimeBetweenFetches * 0.8f, 10.f); - LL_DEBUGS() << "Inventory fetch times shrunk to (" << mMinTimeBetweenFetches << ", " << mMaxTimeBetweenFetches << ")" << LL_ENDL; + LL_DEBUGS(LOG_INV) << "Inventory fetch times shrunk to (" << mMinTimeBetweenFetches << ", " << mMaxTimeBetweenFetches << ")" << LL_ENDL; } mTimelyFetchPending = FALSE; @@ -355,257 +449,53 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() } } -void LLInventoryModelBackgroundFetch::incrFetchCount(S16 fetching) +void LLInventoryModelBackgroundFetch::incrFetchCount(S32 fetching) { mFetchCount += fetching; if (mFetchCount < 0) { + LL_WARNS_ONCE(LOG_INV) << "Inventory fetch count fell below zero (0)." << LL_ENDL; mFetchCount = 0; } } -class LLInventoryModelFetchItemResponder : public LLInventoryModel::fetchInventoryResponder -{ - LOG_CLASS(LLInventoryModelFetchItemResponder); -public: - LLInventoryModelFetchItemResponder(const LLSD& request_sd) : - LLInventoryModel::fetchInventoryResponder(request_sd) - { - LLInventoryModelBackgroundFetch::instance().incrFetchCount(1); - } -private: - /* virtual */ void httpCompleted() - { - LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); - LLInventoryModel::fetchInventoryResponder::httpCompleted(); - } -}; - -class LLInventoryModelFetchDescendentsResponder: public LLHTTPClient::Responder -{ - LOG_CLASS(LLInventoryModelFetchDescendentsResponder); -public: - LLInventoryModelFetchDescendentsResponder(const LLSD& request_sd, uuid_vec_t recursive_cats) : - mRequestSD(request_sd), - mRecursiveCatUUIDs(recursive_cats) - { - LLInventoryModelBackgroundFetch::instance().incrFetchCount(1); - } - //LLInventoryModelFetchDescendentsResponder() {}; -private: - /* virtual */ void httpCompleted() - { - LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); - LLHTTPClient::Responder::httpCompleted(); - } - /* virtual */ void httpSuccess(); - /* virtual */ void httpFailure(); -protected: - BOOL getIsRecursive(const LLUUID& cat_id) const; -private: - LLSD mRequestSD; - uuid_vec_t mRecursiveCatUUIDs; // hack for storing away which cat fetches are recursive -}; - -// If we get back a normal response, handle it here. -void LLInventoryModelFetchDescendentsResponder::httpSuccess() +// Bundle up a bunch of requests to send all at once. +void LLInventoryModelBackgroundFetch::bulkFetch() { - const LLSD& content = getContent(); - if (!content.isMap()) + //Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped. + //If there are items in mFetchQueue, we want to check the time since the last bulkFetch was + //sent. If it exceeds our retry time, go ahead and fire off another batch. + LLViewerRegion * region(gAgent.getRegion()); + if (! region || gDisconnected) { - failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content); return; } - LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance(); - if (content.has("folders")) - { - - for(LLSD::array_const_iterator folder_it = content["folders"].beginArray(); - folder_it != content["folders"].endArray(); - ++folder_it) - { - LLSD folder_sd = *folder_it; - - - //LLUUID agent_id = folder_sd["agent_id"]; - - //if(agent_id != gAgent.getID()) //This should never happen. - //{ - // LL_WARNS() << "Got a UpdateInventoryItem for the wrong agent." - // << LL_ENDL; - // break; - //} - - LLUUID parent_id = folder_sd["folder_id"]; - LLUUID owner_id = folder_sd["owner_id"]; - S32 version = (S32)folder_sd["version"].asInteger(); - S32 descendents = (S32)folder_sd["descendents"].asInteger(); - LLPointer<LLViewerInventoryCategory> tcategory = new LLViewerInventoryCategory(owner_id); - if (parent_id.isNull()) - { - LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem; - for(LLSD::array_const_iterator item_it = folder_sd["items"].beginArray(); - item_it != folder_sd["items"].endArray(); - ++item_it) - { - const LLUUID lost_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); - if (lost_uuid.notNull()) - { - LLSD item = *item_it; - titem->unpackMessage(item); - - LLInventoryModel::update_list_t update; - LLInventoryModel::LLCategoryUpdate new_folder(lost_uuid, 1); - update.push_back(new_folder); - gInventory.accountForUpdate(update); - - titem->setParent(lost_uuid); - titem->updateParentOnServer(FALSE); - gInventory.updateItem(titem); - gInventory.notifyObservers(); - - } - } - } - - LLViewerInventoryCategory* pcat = gInventory.getCategory(parent_id); - if (!pcat) - { - continue; - } - - for(LLSD::array_const_iterator category_it = folder_sd["categories"].beginArray(); - category_it != folder_sd["categories"].endArray(); - ++category_it) - { - LLSD category = *category_it; - tcategory->fromLLSD(category); - - const BOOL recursive = getIsRecursive(tcategory->getUUID()); - - if (recursive) - { - fetcher->mFetchQueue.push_back(LLInventoryModelBackgroundFetch::FetchQueueInfo(tcategory->getUUID(), recursive)); - } - else if ( !gInventory.isCategoryComplete(tcategory->getUUID()) ) - { - gInventory.updateCategory(tcategory); - } - - } - LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem; - for(LLSD::array_const_iterator item_it = folder_sd["items"].beginArray(); - item_it != folder_sd["items"].endArray(); - ++item_it) - { - LLSD item = *item_it; - titem->unpackMessage(item); - - gInventory.updateItem(titem); - } - - // Set version and descendentcount according to message. - LLViewerInventoryCategory* cat = gInventory.getCategory(parent_id); - if(cat) - { - cat->setVersion(version); - cat->setDescendentCount(descendents); - cat->determineFolderType(); - } - - } - } - - if (content.has("bad_folders")) - { - for(LLSD::array_const_iterator folder_it = content["bad_folders"].beginArray(); - folder_it != content["bad_folders"].endArray(); - ++folder_it) - { - // *TODO: Stop copying data - LLSD folder_sd = *folder_it; - - // These folders failed on the dataserver. We probably don't want to retry them. - LL_WARNS() << "Folder " << folder_sd["folder_id"].asString() - << "Error: " << folder_sd["error"].asString() << LL_ENDL; - } - } + static const S32 max_concurrent_fetches(12); // Outstanding requests, not connections + static const F32 new_min_time(0.5f); // *HACK: Clean this up when old code goes away entirely. + static const U32 max_batch_size(10); - if (fetcher->isBulkFetchProcessingComplete()) + if (mMinTimeBetweenFetches < new_min_time) { - LL_INFOS() << "Inventory fetch completed" << LL_ENDL; - fetcher->setAllFoldersFetched(); + mMinTimeBetweenFetches = new_min_time; // *HACK: See above. } - - gInventory.notifyObservers(); -} - -// If we get back an error (not found, etc...), handle it here. -void LLInventoryModelFetchDescendentsResponder::httpFailure() -{ - LL_WARNS() << dumpResponse() << LL_ENDL; - LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance(); - - LL_INFOS() << dumpResponse() << LL_ENDL; - - fetcher->incrFetchCount(-1); - if (getStatus()==HTTP_INTERNAL_ERROR) // timed out or curl failure - { - for(LLSD::array_const_iterator folder_it = mRequestSD["folders"].beginArray(); - folder_it != mRequestSD["folders"].endArray(); - ++folder_it) - { - LLSD folder_sd = *folder_it; - LLUUID folder_id = folder_sd["folder_id"]; - const BOOL recursive = getIsRecursive(folder_id); - fetcher->mFetchQueue.push_front(LLInventoryModelBackgroundFetch::FetchQueueInfo(folder_id, recursive)); - } - } - else + if (mFetchCount) { - if (fetcher->isBulkFetchProcessingComplete()) - { - fetcher->setAllFoldersFetched(); - } - } - gInventory.notifyObservers(); -} - -BOOL LLInventoryModelFetchDescendentsResponder::getIsRecursive(const LLUUID& cat_id) const -{ - return (std::find(mRecursiveCatUUIDs.begin(),mRecursiveCatUUIDs.end(), cat_id) != mRecursiveCatUUIDs.end()); -} -// Bundle up a bunch of requests to send all at once. -// static -void LLInventoryModelBackgroundFetch::bulkFetch() -{ - //Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped. - //If there are items in mFetchQueue, we want to check the time since the last bulkFetch was - //sent. If it exceeds our retry time, go ahead and fire off another batch. - LLViewerRegion* region = gAgent.getRegion(); - if (!region) return; - - S16 max_concurrent_fetches=8; - F32 new_min_time = 0.5f; //HACK! Clean this up when old code goes away entirely. - if (mMinTimeBetweenFetches < new_min_time) - { - mMinTimeBetweenFetches=new_min_time; //HACK! See above. + // Process completed HTTP requests + gInventory.handleResponses(false); } - if (gDisconnected || - (mFetchCount > max_concurrent_fetches) || + if ((mFetchCount > max_concurrent_fetches) || (mFetchTimer.getElapsedTimeF32() < mMinTimeBetweenFetches)) { - return; // just bail if we are disconnected + return; } - U32 item_count=0; - U32 folder_count=0; - U32 max_batch_size=5; + U32 item_count(0); + U32 folder_count(0); - U32 sort_order = gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER) & 0x1; + const U32 sort_order(gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER) & 0x1); uuid_vec_t recursive_cats; @@ -614,27 +504,27 @@ void LLInventoryModelBackgroundFetch::bulkFetch() LLSD item_request_body; LLSD item_request_body_lib; - while (!mFetchQueue.empty() + while (! mFetchQueue.empty() && (item_count + folder_count) < max_batch_size) { - const FetchQueueInfo& fetch_info = mFetchQueue.front(); + const FetchQueueInfo & fetch_info(mFetchQueue.front()); if (fetch_info.mIsCategory) { - const LLUUID &cat_id = fetch_info.mUUID; + const LLUUID & cat_id(fetch_info.mUUID); if (cat_id.isNull()) //DEV-17797 { LLSD folder_sd; folder_sd["folder_id"] = LLUUID::null.asString(); folder_sd["owner_id"] = gAgent.getID(); - folder_sd["sort_order"] = (LLSD::Integer)sort_order; - folder_sd["fetch_folders"] = (LLSD::Boolean)FALSE; - folder_sd["fetch_items"] = (LLSD::Boolean)TRUE; + folder_sd["sort_order"] = LLSD::Integer(sort_order); + folder_sd["fetch_folders"] = LLSD::Boolean(FALSE); + folder_sd["fetch_items"] = LLSD::Boolean(TRUE); folder_request_body["folders"].append(folder_sd); folder_count++; } else { - const LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); + const LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id)); if (cat) { @@ -643,21 +533,26 @@ void LLInventoryModelBackgroundFetch::bulkFetch() LLSD folder_sd; folder_sd["folder_id"] = cat->getUUID(); folder_sd["owner_id"] = cat->getOwnerID(); - folder_sd["sort_order"] = (LLSD::Integer)sort_order; - folder_sd["fetch_folders"] = TRUE; //(LLSD::Boolean)sFullFetchStarted; - folder_sd["fetch_items"] = (LLSD::Boolean)TRUE; + folder_sd["sort_order"] = LLSD::Integer(sort_order); + folder_sd["fetch_folders"] = LLSD::Boolean(TRUE); //(LLSD::Boolean)sFullFetchStarted; + folder_sd["fetch_items"] = LLSD::Boolean(TRUE); if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) + { folder_request_body_lib["folders"].append(folder_sd); + } else + { folder_request_body["folders"].append(folder_sd); + } folder_count++; } + // May already have this folder, but append child folders to list. if (fetch_info.mRecursive) { - LLInventoryModel::cat_array_t* categories; - LLInventoryModel::item_array_t* items; + LLInventoryModel::cat_array_t * categories(NULL); + LLInventoryModel::item_array_t * items(NULL); gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items); for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); it != categories->end(); @@ -669,11 +564,14 @@ void LLInventoryModelBackgroundFetch::bulkFetch() } } if (fetch_info.mRecursive) + { recursive_cats.push_back(cat_id); + } } else { - LLViewerInventoryItem* itemp = gInventory.getItem(fetch_info.mUUID); + LLViewerInventoryItem * itemp(gInventory.getItem(fetch_info.mUUID)); + if (itemp) { LLSD item_sd; @@ -694,72 +592,80 @@ void LLInventoryModelBackgroundFetch::bulkFetch() mFetchQueue.pop_front(); } - + + // Issue HTTP POST requests to fetch folders and items + if (item_count + folder_count > 0) { if (folder_count) { - std::string url = region->getCapability("FetchInventoryDescendents2"); - if ( !url.empty() ) + if (folder_request_body["folders"].size()) { - if (folder_request_body["folders"].size()) + const std::string url(region->getCapability("FetchInventoryDescendents2")); + + if (! url.empty()) { - LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats); - LLHTTPClient::post(url, folder_request_body, fetcher, 300.0); + BGFolderHttpHandler * handler(new BGFolderHttpHandler(folder_request_body, recursive_cats)); + gInventory.requestPost(false, url, folder_request_body, handler, "Inventory Folder"); } - if (folder_request_body_lib["folders"].size()) - { - std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2"); + } + + if (folder_request_body_lib["folders"].size()) + { + const std::string url(region->getCapability("FetchLibDescendents2")); - LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats); - LLHTTPClient::post(url_lib, folder_request_body_lib, fetcher, 300.0); + if (! url.empty()) + { + BGFolderHttpHandler * handler(new BGFolderHttpHandler(folder_request_body_lib, recursive_cats)); + gInventory.requestPost(false, url, folder_request_body_lib, handler, "Library Folder"); } } - } + } // if (folder_count) + if (item_count) { - std::string url; - if (item_request_body.size()) { - url = region->getCapability("FetchInventory2"); - if (!url.empty()) + const std::string url(region->getCapability("FetchInventory2")); + + if (! url.empty()) { LLSD body; body["items"] = item_request_body; - - LLHTTPClient::post(url, body, new LLInventoryModelFetchItemResponder(body)); + BGItemHttpHandler * handler(new BGItemHttpHandler(body)); + gInventory.requestPost(false, url, body, handler, "Inventory Item"); } } if (item_request_body_lib.size()) { + const std::string url(region->getCapability("FetchLib2")); - url = region->getCapability("FetchLib2"); - if (!url.empty()) + if (! url.empty()) { LLSD body; body["items"] = item_request_body_lib; - - LLHTTPClient::post(url, body, new LLInventoryModelFetchItemResponder(body)); + BGItemHttpHandler * handler(new BGItemHttpHandler(body)); + gInventory.requestPost(false, url, body, handler, "Library Item"); } } - } + } // if (item_count) + mFetchTimer.reset(); } - else if (isBulkFetchProcessingComplete()) { setAllFoldersFetched(); } } -bool LLInventoryModelBackgroundFetch::fetchQueueContainsNoDescendentsOf(const LLUUID& cat_id) const +bool LLInventoryModelBackgroundFetch::fetchQueueContainsNoDescendentsOf(const LLUUID & cat_id) const { for (fetch_queue_t::const_iterator it = mFetchQueue.begin(); - it != mFetchQueue.end(); ++it) + it != mFetchQueue.end(); + ++it) { - const LLUUID& fetch_id = (*it).mUUID; + const LLUUID & fetch_id = (*it).mUUID; if (gInventory.isObjectDescendentOf(fetch_id, cat_id)) return false; } @@ -767,3 +673,257 @@ bool LLInventoryModelBackgroundFetch::fetchQueueContainsNoDescendentsOf(const LL } +// Anonymous Namespace Definitions + +namespace +{ + +// ==== BGFolderHttpHandler ==== + +void BGFolderHttpHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response) +{ + LLCore::HttpStatus status(response->getStatus()); + if (! status) + { + processFailure(status, response); + } + else + { + LLCore::BufferArray * body(response->getBody()); + if (! body || ! body->size()) + { + LL_WARNS(LOG_INV) << "Missing data in inventory folder query." << LL_ENDL; + processFailure("HTTP response missing expected body", response); + goto only_exit; + } + + LLCore::BufferArrayStream bas(body); + LLSD body_llsd; + S32 parse_status(LLSDSerialize::fromXML(body_llsd, bas)); + if (LLSDParser::PARSE_FAILURE == parse_status) + { + // INFOS-level logging will occur on the parsed failure + processFailure("HTTP response contained malformed LLSD", response); + goto only_exit; + } + + // Okay, process data if possible + processData(body_llsd, response); + } + +only_exit: + // Must delete on completion. + delete this; +} + + +void BGFolderHttpHandler::processData(LLSD & content, LLCore::HttpResponse * response) +{ + if (! content.isMap()) + { + processFailure("LLSD response not a map", response); + return; + } + + LLInventoryModelBackgroundFetch * fetcher(LLInventoryModelBackgroundFetch::getInstance()); + if (content.has("folders")) + { + LLSD folders(content["folders"]); + + for (LLSD::array_const_iterator folder_it = folders.beginArray(); + folder_it != folders.endArray(); + ++folder_it) + { + LLSD folder_sd(*folder_it); + + //LLUUID agent_id = folder_sd["agent_id"]; + + //if(agent_id != gAgent.getID()) //This should never happen. + //{ + // LL_WARNS(LOG_INV) << "Got a UpdateInventoryItem for the wrong agent." + // << LL_ENDL; + // break; + //} + + LLUUID parent_id(folder_sd["folder_id"].asUUID()); + LLUUID owner_id(folder_sd["owner_id"].asUUID()); + S32 version(folder_sd["version"].asInteger()); + S32 descendents(folder_sd["descendents"].asInteger()); + LLPointer<LLViewerInventoryCategory> tcategory = new LLViewerInventoryCategory(owner_id); + + if (parent_id.isNull()) + { + LLSD items(folder_sd["items"]); + LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem; + + for (LLSD::array_const_iterator item_it = items.beginArray(); + item_it != items.endArray(); + ++item_it) + { + const LLUUID lost_uuid(gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND)); + + if (lost_uuid.notNull()) + { + LLSD item(*item_it); + + titem->unpackMessage(item); + + LLInventoryModel::update_list_t update; + LLInventoryModel::LLCategoryUpdate new_folder(lost_uuid, 1); + update.push_back(new_folder); + gInventory.accountForUpdate(update); + + titem->setParent(lost_uuid); + titem->updateParentOnServer(FALSE); + gInventory.updateItem(titem); + gInventory.notifyObservers(); + } + } + } + + LLViewerInventoryCategory * pcat(gInventory.getCategory(parent_id)); + if (! pcat) + { + continue; + } + + LLSD categories(folder_sd["categories"]); + for (LLSD::array_const_iterator category_it = categories.beginArray(); + category_it != categories.endArray(); + ++category_it) + { + LLSD category(*category_it); + tcategory->fromLLSD(category); + + const bool recursive(getIsRecursive(tcategory->getUUID())); + if (recursive) + { + fetcher->addRequestAtBack(tcategory->getUUID(), recursive, true); + } + else if (! gInventory.isCategoryComplete(tcategory->getUUID())) + { + gInventory.updateCategory(tcategory); + } + } + + LLSD items(folder_sd["items"]); + LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem; + for (LLSD::array_const_iterator item_it = items.beginArray(); + item_it != items.endArray(); + ++item_it) + { + LLSD item(*item_it); + titem->unpackMessage(item); + + gInventory.updateItem(titem); + } + + // Set version and descendentcount according to message. + LLViewerInventoryCategory * cat(gInventory.getCategory(parent_id)); + if (cat) + { + cat->setVersion(version); + cat->setDescendentCount(descendents); + cat->determineFolderType(); + } + } + } + + if (content.has("bad_folders")) + { + LLSD bad_folders(content["bad_folders"]); + for (LLSD::array_const_iterator folder_it = bad_folders.beginArray(); + folder_it != bad_folders.endArray(); + ++folder_it) + { + // *TODO: Stop copying data + LLSD folder_sd(*folder_it); + + // These folders failed on the dataserver. We probably don't want to retry them. + LL_WARNS(LOG_INV) << "Folder " << folder_sd["folder_id"].asString() + << "Error: " << folder_sd["error"].asString() << LL_ENDL; + } + } + + if (fetcher->isBulkFetchProcessingComplete()) + { + LL_INFOS(LOG_INV) << "Inventory fetch completed" << LL_ENDL; + fetcher->setAllFoldersFetched(); + } + + gInventory.notifyObservers(); +} + + +void BGFolderHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::HttpResponse * response) +{ + LL_WARNS(LOG_INV) << dumpResponse() << LL_ENDL; + LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance(); + + LL_INFOS(LOG_INV) << dumpResponse() << LL_ENDL; + + // *FIX: Not the correct test here... + if (status == LLCore::HttpStatus(408)) // timed out or curl failure + { + for (LLSD::array_const_iterator folder_it = mRequestSD["folders"].beginArray(); + folder_it != mRequestSD["folders"].endArray(); + ++folder_it) + { + LLSD folder_sd(*folder_it); + LLUUID folder_id(folder_sd["folder_id"]); + const BOOL recursive = getIsRecursive(folder_id); + fetcher->addRequestAtFront(folder_id, recursive, true); + } + } + else + { + if (fetcher->isBulkFetchProcessingComplete()) + { + fetcher->setAllFoldersFetched(); + } + } + gInventory.notifyObservers(); +} + + +void BGFolderHttpHandler::processFailure(const char * const reason, LLCore::HttpResponse * response) +{ + LL_WARNS(LOG_INV) << dumpResponse() << LL_ENDL; + LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance(); + + LL_INFOS(LOG_INV) << dumpResponse() << LL_ENDL; + + if (true /* status == LLCore::HttpStatus(408)*/) // timed out or curl failure + { + for (LLSD::array_const_iterator folder_it = mRequestSD["folders"].beginArray(); + folder_it != mRequestSD["folders"].endArray(); + ++folder_it) + { + LLSD folder_sd(*folder_it); + LLUUID folder_id(folder_sd["folder_id"]); + const BOOL recursive = getIsRecursive(folder_id); + fetcher->addRequestAtFront(folder_id, recursive, true); + } + } + else + { + if (fetcher->isBulkFetchProcessingComplete()) + { + fetcher->setAllFoldersFetched(); + } + } + gInventory.notifyObservers(); +} + + +bool BGFolderHttpHandler::getIsRecursive(const LLUUID & cat_id) const +{ + return std::find(mRecursiveCatUUIDs.begin(), mRecursiveCatUUIDs.end(), cat_id) != mRecursiveCatUUIDs.end(); +} + + +// ==== BGItemHttpHandler ==== + +// Nothing to implement here. All ctor/dtor changes. + +} // end namespace anonymous diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index 9dfedddd6d..2139f85519 100755 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -29,6 +29,11 @@ #include "llsingleton.h" #include "lluuid.h" +#include "httpcommon.h" +#include "httprequest.h" +#include "httpoptions.h" +#include "httpheaders.h" +#include "httphandler.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLInventoryModelBackgroundFetch @@ -38,8 +43,6 @@ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLInventoryModelBackgroundFetch : public LLSingleton<LLInventoryModelBackgroundFetch> { - friend class LLInventoryModelFetchDescendentsResponder; - public: LLInventoryModelBackgroundFetch(); ~LLInventoryModelBackgroundFetch(); @@ -60,16 +63,22 @@ public: bool inventoryFetchInProgress() const; void findLostItems(); - void incrFetchCount(S16 fetching); -protected: + void incrFetchCount(S32 fetching); + bool isBulkFetchProcessingComplete() const; + void setAllFoldersFetched(); + + void addRequestAtFront(const LLUUID & id, BOOL recursive, bool is_category); + void addRequestAtBack(const LLUUID & id, BOOL recursive, bool is_category); + +protected: void bulkFetch(); void backgroundFetch(); static void backgroundFetchCB(void*); // background fetch idle function - void setAllFoldersFetched(); bool fetchQueueContainsNoDescendentsOf(const LLUUID& cat_id) const; + private: BOOL mRecursiveInventoryFetchStarted; BOOL mRecursiveLibraryFetchStarted; @@ -77,7 +86,7 @@ private: BOOL mBackgroundFetchActive; bool mFolderFetchActive; - S16 mFetchCount; + S32 mFetchCount; BOOL mTimelyFetchPending; S32 mNumFetchRetries; @@ -87,9 +96,12 @@ private: struct FetchQueueInfo { - FetchQueueInfo(const LLUUID& id, BOOL recursive, bool is_category = true) : - mUUID(id), mRecursive(recursive), mIsCategory(is_category) + FetchQueueInfo(const LLUUID& id, BOOL recursive, bool is_category = true) + : mUUID(id), + mIsCategory(is_category), + mRecursive(recursive) {} + LLUUID mUUID; bool mIsCategory; BOOL mRecursive; diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index 2dd8dce42f..d81401b59b 100755 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -237,7 +237,8 @@ void fetch_items_from_llsd(const LLSD& items_llsd) if (!url.empty()) { body[i]["agent_id"] = gAgent.getID(); - LLHTTPClient::post(url, body[i], new LLInventoryModel::fetchInventoryResponder(body[i])); + LLInventoryModel::FetchItemHttpHandler * handler(new LLInventoryModel::FetchItemHttpHandler(body[i])); + gInventory.requestPost(true, url, body[i], handler, (i ? "Library Item" : "Inventory Item")); continue; } diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index f61db77169..942360b650 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2013&license=viewerlgpl$ * Second Life Viewer Source Code -* Copyright (C) 2013, Linden Research, Inc. +* Copyright (C) 2014, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -151,7 +151,7 @@ F32 LLSnapshotLivePreview::getImageAspect() void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail, F32 delay) { - lldebugs << "updateSnapshot: mSnapshotUpToDate = " << getSnapshotUpToDate() << llendl; + LL_DEBUGS() << "updateSnapshot: mSnapshotUpToDate = " << getSnapshotUpToDate() << LL_ENDL; // Update snapshot if requested. if (new_snapshot) @@ -594,7 +594,7 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update) } else { - llwarns << "Couldn't find a path to the following filter : " << getFilter() << llendl; + LL_WARNS() << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL; } } // Scale to a power of 2 so it can be mapped to a texture @@ -642,7 +642,7 @@ LLViewerTexture* LLSnapshotLivePreview::getBigThumbnailImage() } else { - llwarns << "Couldn't find a path to the following filter : " << getFilter() << llendl; + LL_WARNS() << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL; } } // Scale to a power of 2 so it can be mapped to a texture @@ -695,7 +695,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) // time to produce a snapshot if(!previewp->getSnapshotUpToDate()) { - lldebugs << "producing snapshot" << llendl; + LL_DEBUGS() << "producing snapshot" << LL_ENDL; if (!previewp->mPreviewImage) { previewp->mPreviewImage = new LLImageRaw; @@ -775,7 +775,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame") && previewp->mAllowFullScreenPreview); // only show fullscreen preview when in freeze frame mode previewp->mSnapshotDelayTimer.stop(); previewp->mSnapshotActive = FALSE; - lldebugs << "done creating snapshot" << llendl; + LL_DEBUGS() << "done creating snapshot" << LL_ENDL; } if (!previewp->getThumbnailUpToDate()) @@ -910,13 +910,13 @@ LLPointer<LLImageFormatted> LLSnapshotLivePreview::getFormattedImage() } else { - llwarns << "Couldn't find a path to the following filter : " << getFilter() << llendl; + LL_WARNS() << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL; } } // Create the new formatted image of the appropriate format. LLFloaterSnapshot::ESnapshotFormat format = getSnapshotFormat(); - lldebugs << "Encoding new image of format " << format << llendl; + LL_DEBUGS() << "Encoding new image of format " << format << LL_ENDL; switch (format) { diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 4e4c3471be..d364fce45a 100755 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2014, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -75,6 +75,10 @@ void no_op_inventory_func(const LLUUID&) {} void no_op_llsd_func(const LLSD&) {} void no_op() {} +static const char * const LOG_INV("Inventory"); +static const char * const LOG_LOCAL("InventoryLocalize"); +static const char * const LOG_NOTECARD("copy_inventory_from_notecard"); + ///---------------------------------------------------------------------------- /// Helper class to store special inventory item names and their localized values. ///---------------------------------------------------------------------------- @@ -189,7 +193,7 @@ public: */ bool localizeInventoryObjectName(std::string& object_name) { - LL_DEBUGS("InventoryLocalize") << "Searching for localization: " << object_name << LL_ENDL; + LL_DEBUGS(LOG_LOCAL) << "Searching for localization: " << object_name << LL_ENDL; std::map<std::string, std::string>::const_iterator dictionary_iter = mInventoryItemsDict.find(object_name); @@ -197,7 +201,7 @@ public: if(found) { object_name = dictionary_iter->second; - LL_DEBUGS("InventoryLocalize") << "Found, new name is: " << object_name << LL_ENDL; + LL_DEBUGS(LOG_LOCAL) << "Found, new name is: " << object_name << LL_ENDL; } return found; } @@ -307,8 +311,8 @@ LLViewerInventoryItem::LLViewerInventoryItem(const LLViewerInventoryItem* other) copyViewerItem(other); if (!mIsComplete) { - LL_WARNS() << "LLViewerInventoryItem copy constructor for incomplete item" - << mUUID << LL_ENDL; + LL_WARNS(LOG_INV) << "LLViewerInventoryItem copy constructor for incomplete item" + << mUUID << LL_ENDL; } } @@ -355,16 +359,16 @@ void LLViewerInventoryItem::updateServer(BOOL is_new) const { // *FIX: deal with this better. // If we're crashing here then the UI is incorrectly enabled. - LL_ERRS() << "LLViewerInventoryItem::updateServer() - for incomplete item" - << LL_ENDL; + LL_ERRS(LOG_INV) << "LLViewerInventoryItem::updateServer() - for incomplete item" + << LL_ENDL; return; } if(gAgent.getID() != mPermissions.getOwner()) { // *FIX: deal with this better. - LL_WARNS() << "LLViewerInventoryItem::updateServer() - for unowned item " - << ll_pretty_print_sd(this->asLLSD()) - << LL_ENDL; + LL_WARNS(LOG_INV) << "LLViewerInventoryItem::updateServer() - for unowned item " + << ll_pretty_print_sd(this->asLLSD()) + << LL_ENDL; return; } LLInventoryModel::LLCategoryUpdate up(mParentUUID, is_new ? 1 : 0); @@ -392,18 +396,18 @@ void LLViewerInventoryItem::fetchFromServer(void) const // we have to check region. It can be null after region was destroyed. See EXT-245 if (region) { - if(gAgent.getID() != mPermissions.getOwner()) - { + if (gAgent.getID() != mPermissions.getOwner()) + { url = region->getCapability("FetchLib2"); - } + } else - { + { url = region->getCapability("FetchInventory2"); - } + } } else { - LL_WARNS() << "Agent Region is absent" << LL_ENDL; + LL_WARNS(LOG_INV) << "Agent Region is absent" << LL_ENDL; } if (!url.empty()) @@ -413,7 +417,8 @@ void LLViewerInventoryItem::fetchFromServer(void) const body["items"][0]["owner_id"] = mPermissions.getOwner(); body["items"][0]["item_id"] = mUUID; - LLHTTPClient::post(url, body, new LLInventoryModel::fetchInventoryResponder(body)); + LLInventoryModel::FetchItemHttpHandler * handler(new LLInventoryModel::FetchItemHttpHandler(body)); + gInventory.requestPost(true, url, body, handler, "Inventory Item"); } else { @@ -649,7 +654,7 @@ bool LLViewerInventoryCategory::fetch() if((VERSION_UNKNOWN == getVersion()) && mDescendentsRequested.hasExpired()) //Expired check prevents multiple downloads. { - LL_DEBUGS("InventoryFetch") << "Fetching category children: " << mName << ", UUID: " << mUUID << LL_ENDL; + LL_DEBUGS(LOG_INV) << "Fetching category children: " << mName << ", UUID: " << mUUID << LL_ENDL; const F32 FETCH_TIMER_EXPIRY = 10.0f; mDescendentsRequested.reset(); mDescendentsRequested.setTimerExpirySec(FETCH_TIMER_EXPIRY); @@ -674,7 +679,7 @@ bool LLViewerInventoryCategory::fetch() } else { - LL_WARNS() << "agent region is null" << LL_ENDL; + LL_WARNS(LOG_INV) << "agent region is null" << LL_ENDL; } if (!url.empty()) //Capability found. Build up LLSD and use it. { @@ -682,7 +687,8 @@ bool LLViewerInventoryCategory::fetch() } else { //Deprecated, but if we don't have a capability, use the old system. - LL_INFOS() << "FetchInventoryDescendents2 capability not found. Using deprecated UDP message." << LL_ENDL; + LL_INFOS(LOG_INV) << "FetchInventoryDescendents2 capability not found. Using deprecated UDP message." << LL_ENDL; + LLMessageSystem* msg = gMessageSystem; msg->newMessage("FetchInventoryDescendents"); msg->nextBlock("AgentData"); @@ -777,8 +783,8 @@ bool LLViewerInventoryCategory::importFileLocal(LLFILE* fp) } else { - LL_WARNS() << "unknown keyword '" << keyword - << "' in inventory import category " << mUUID << LL_ENDL; + LL_WARNS(LOG_INV) << "unknown keyword '" << keyword + << "' in inventory import category " << mUUID << LL_ENDL; } } return true; @@ -906,7 +912,7 @@ LLInventoryCallbackManager::LLInventoryCallbackManager() : { if( sInstance != NULL ) { - LL_WARNS() << "LLInventoryCallbackManager::LLInventoryCallbackManager: unexpected multiple instances" << LL_ENDL; + LL_WARNS(LOG_INV) << "LLInventoryCallbackManager::LLInventoryCallbackManager: unexpected multiple instances" << LL_ENDL; return; } sInstance = this; @@ -916,7 +922,7 @@ LLInventoryCallbackManager::~LLInventoryCallbackManager() { if( sInstance != this ) { - LL_WARNS() << "LLInventoryCallbackManager::~LLInventoryCallbackManager: unexpected multiple instances" << LL_ENDL; + LL_WARNS(LOG_INV) << "LLInventoryCallbackManager::~LLInventoryCallbackManager: unexpected multiple instances" << LL_ENDL; return; } sInstance = NULL; @@ -1144,7 +1150,7 @@ void link_inventory_object(const LLUUID& category, { if (!baseobj) { - LL_WARNS() << "Attempt to link to non-existent object" << LL_ENDL; + LL_WARNS(LOG_INV) << "Attempt to link to non-existent object" << LL_ENDL; return; } @@ -1178,7 +1184,7 @@ void link_inventory_array(const LLUUID& category, const LLInventoryObject* baseobj = *it; if (!baseobj) { - LL_WARNS() << "attempt to link to unknown object" << LL_ENDL; + LL_WARNS(LOG_INV) << "attempt to link to unknown object" << LL_ENDL; continue; } @@ -1187,7 +1193,7 @@ void link_inventory_array(const LLUUID& category, // Fail if item can be found but is of a type that can't be linked. // Arguably should fail if the item can't be found too, but that could // be a larger behavioral change. - LL_WARNS() << "attempt to link an unlinkable object, type = " << baseobj->getActualType() << LL_ENDL; + LL_WARNS(LOG_INV) << "attempt to link an unlinkable object, type = " << baseobj->getActualType() << LL_ENDL; continue; } @@ -1223,7 +1229,7 @@ void link_inventory_array(const LLUUID& category, } else { - LL_WARNS() << "could not convert object into an item or category: " << baseobj->getUUID() << LL_ENDL; + LL_WARNS(LOG_INV) << "could not convert object into an item or category: " << baseobj->getUUID() << LL_ENDL; continue; } } @@ -1237,10 +1243,10 @@ void link_inventory_array(const LLUUID& category, links.append(link); #ifndef LL_RELEASE_FOR_DOWNLOAD - LL_DEBUGS("Inventory") << "Linking Object [ name:" << baseobj->getName() - << " UUID:" << baseobj->getUUID() - << " ] into Category [ name:" << cat_name - << " UUID:" << category << " ] " << LL_ENDL; + LL_DEBUGS(LOG_INV) << "Linking Object [ name:" << baseobj->getName() + << " UUID:" << baseobj->getUUID() + << " ] into Category [ name:" << cat_name + << " UUID:" << category << " ] " << LL_ENDL; #endif } @@ -1331,7 +1337,7 @@ void update_inventory_item( if (!ais_ran) { LLPointer<LLViewerInventoryItem> obj = gInventory.getItem(item_id); - LL_DEBUGS("Inventory") << "item_id: [" << item_id << "] name " << (update_item ? update_item->getName() : "(NOT FOUND)") << LL_ENDL; + LL_DEBUGS(LOG_INV) << "item_id: [" << item_id << "] name " << (update_item ? update_item->getName() : "(NOT FOUND)") << LL_ENDL; if(obj) { LLMessageSystem* msg = gMessageSystem; @@ -1373,7 +1379,7 @@ void update_inventory_item( if (!ais_ran) { LLPointer<LLViewerInventoryItem> obj = gInventory.getItem(item_id); - LL_DEBUGS("Inventory") << "item_id: [" << item_id << "] name " << (obj ? obj->getName() : "(NOT FOUND)") << LL_ENDL; + LL_DEBUGS(LOG_INV) << "item_id: [" << item_id << "] name " << (obj ? obj->getName() : "(NOT FOUND)") << LL_ENDL; if(obj) { LLPointer<LLViewerInventoryItem> new_item(new LLViewerInventoryItem); @@ -1408,7 +1414,7 @@ void update_inventory_category( LLPointer<LLInventoryCallback> cb) { LLPointer<LLViewerInventoryCategory> obj = gInventory.getCategory(cat_id); - LL_DEBUGS("Inventory") << "cat_id: [" << cat_id << "] name " << (obj ? obj->getName() : "(NOT FOUND)") << LL_ENDL; + LL_DEBUGS(LOG_INV) << "cat_id: [" << cat_id << "] name " << (obj ? obj->getName() : "(NOT FOUND)") << LL_ENDL; if(obj) { if (LLFolderType::lookupIsProtectedType(obj->getPreferredType())) @@ -1471,7 +1477,7 @@ void remove_inventory_item( } else { - LL_DEBUGS("Inventory") << "item_id: [" << item_id << "] name " << "(NOT FOUND)" << LL_ENDL; + LL_DEBUGS(LOG_INV) << "item_id: [" << item_id << "] name " << "(NOT FOUND)" << LL_ENDL; } } @@ -1482,7 +1488,7 @@ void remove_inventory_item( if(obj) { const LLUUID item_id(obj->getUUID()); - LL_DEBUGS("Inventory") << "item_id: [" << item_id << "] name " << obj->getName() << LL_ENDL; + LL_DEBUGS(LOG_INV) << "item_id: [" << item_id << "] name " << obj->getName() << LL_ENDL; if (AISCommand::isAPIAvailable()) { LLPointer<AISCommand> cmd_ptr = new RemoveItemCommand(item_id, cb); @@ -1511,7 +1517,7 @@ void remove_inventory_item( else { // *TODO: Clean up callback? - LL_WARNS() << "remove_inventory_item called for invalid or nonexistent item." << LL_ENDL; + LL_WARNS(LOG_INV) << "remove_inventory_item called for invalid or nonexistent item." << LL_ENDL; } } @@ -1529,7 +1535,7 @@ public: LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(mID); if(children != LLInventoryModel::CHILDREN_NO) { - LL_WARNS() << "remove descendents failed, cannot remove category " << LL_ENDL; + LL_WARNS(LOG_INV) << "remove descendents failed, cannot remove category " << LL_ENDL; } else { @@ -1545,7 +1551,7 @@ void remove_inventory_category( const LLUUID& cat_id, LLPointer<LLInventoryCallback> cb) { - LL_DEBUGS("Inventory") << "cat_id: [" << cat_id << "] " << LL_ENDL; + LL_DEBUGS(LOG_INV) << "cat_id: [" << cat_id << "] " << LL_ENDL; LLPointer<LLViewerInventoryCategory> obj = gInventory.getCategory(cat_id); if(obj) { @@ -1566,7 +1572,7 @@ void remove_inventory_category( LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(cat_id); if(children != LLInventoryModel::CHILDREN_NO) { - LL_DEBUGS("Inventory") << "Will purge descendents first before deleting category " << cat_id << LL_ENDL; + LL_DEBUGS(LOG_INV) << "Will purge descendents first before deleting category " << cat_id << LL_ENDL; LLPointer<LLInventoryCallback> wrap_cb = new LLRemoveCategoryOnDestroy(cat_id, cb); purge_descendents_of(cat_id, wrap_cb); return; @@ -1592,7 +1598,7 @@ void remove_inventory_category( } else { - LL_WARNS() << "remove_inventory_category called for invalid or nonexistent item " << cat_id << LL_ENDL; + LL_WARNS(LOG_INV) << "remove_inventory_category called for invalid or nonexistent item " << cat_id << LL_ENDL; } } @@ -1620,7 +1626,7 @@ void purge_descendents_of(const LLUUID& id, LLPointer<LLInventoryCallback> cb) LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(id); if(children == LLInventoryModel::CHILDREN_NO) { - LL_DEBUGS("Inventory") << "No descendents to purge for " << id << LL_ENDL; + LL_DEBUGS(LOG_INV) << "No descendents to purge for " << id << LL_ENDL; return; } LLPointer<LLViewerInventoryCategory> cat = gInventory.getCategory(id); @@ -1629,8 +1635,8 @@ void purge_descendents_of(const LLUUID& id, LLPointer<LLInventoryCallback> cb) if (LLClipboard::instance().hasContents() && LLClipboard::instance().isCutMode()) { // Something on the clipboard is in "cut mode" and needs to be preserved - LL_DEBUGS("Inventory") << "purge_descendents_of clipboard case " << cat->getName() - << " iterate and purge non hidden items" << LL_ENDL; + LL_DEBUGS(LOG_INV) << "purge_descendents_of clipboard case " << cat->getName() + << " iterate and purge non hidden items" << LL_ENDL; LLInventoryModel::cat_array_t* categories; LLInventoryModel::item_array_t* items; // Get the list of direct descendants in tha categoy passed as argument @@ -1665,7 +1671,7 @@ void purge_descendents_of(const LLUUID& id, LLPointer<LLInventoryCallback> cb) else // no cap { // Fast purge - LL_DEBUGS("Inventory") << "purge_descendents_of fast case " << cat->getName() << LL_ENDL; + LL_DEBUGS(LOG_INV) << "purge_descendents_of fast case " << cat->getName() << LL_ENDL; // send it upstream LLMessageSystem* msg = gMessageSystem; @@ -1708,9 +1714,9 @@ void copy_inventory_from_notecard(const LLUUID& destination_id, { if (NULL == src) { - LL_WARNS("copy_inventory_from_notecard") << "Null pointer to item was passed for object_id " - << object_id << " and notecard_inv_id " - << notecard_inv_id << LL_ENDL; + LL_WARNS(LOG_NOTECARD) << "Null pointer to item was passed for object_id " + << object_id << " and notecard_inv_id " + << notecard_inv_id << LL_ENDL; return; } @@ -1730,9 +1736,9 @@ void copy_inventory_from_notecard(const LLUUID& destination_id, if (! viewer_region) { - LL_WARNS("copy_inventory_from_notecard") << "Can't find region from object_id " - << object_id << " or gAgent" - << LL_ENDL; + LL_WARNS(LOG_NOTECARD) << "Can't find region from object_id " + << object_id << " or gAgent" + << LL_ENDL; return; } @@ -1740,9 +1746,9 @@ void copy_inventory_from_notecard(const LLUUID& destination_id, std::string url = viewer_region->getCapability("CopyInventoryFromNotecard"); if (url.empty()) { - LL_WARNS("copy_inventory_from_notecard") << "There is no 'CopyInventoryFromNotecard' capability" - << " for region: " << viewer_region->getName() - << LL_ENDL; + LL_WARNS(LOG_NOTECARD) << "There is no 'CopyInventoryFromNotecard' capability" + << " for region: " << viewer_region->getName() + << LL_ENDL; return; } @@ -1816,15 +1822,15 @@ void slam_inventory_folder(const LLUUID& folder_id, { if (AISCommand::isAPIAvailable()) { - LL_DEBUGS("Avatar") << "using AISv3 to slam folder, id " << folder_id - << " new contents: " << ll_pretty_print_sd(contents) << LL_ENDL; + LL_DEBUGS(LOG_INV) << "using AISv3 to slam folder, id " << folder_id + << " new contents: " << ll_pretty_print_sd(contents) << LL_ENDL; LLPointer<AISCommand> cmd_ptr = new SlamFolderCommand(folder_id, contents, cb); cmd_ptr->run_command(); } else // no cap { - LL_DEBUGS("Avatar") << "using item-by-item calls to slam folder, id " << folder_id - << " new contents: " << ll_pretty_print_sd(contents) << LL_ENDL; + LL_DEBUGS(LOG_INV) << "using item-by-item calls to slam folder, id " << folder_id + << " new contents: " << ll_pretty_print_sd(contents) << LL_ENDL; for (LLSD::array_const_iterator it = contents.beginArray(); it != contents.endArray(); ++it) @@ -1926,7 +1932,7 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge, } else { - LL_WARNS() << "Can't create unrecognized type " << type_name << LL_ENDL; + LL_WARNS(LOG_INV) << "Can't create unrecognized type " << type_name << LL_ENDL; } } panel->getRootFolder()->setNeedsAutoRename(TRUE); @@ -2161,7 +2167,7 @@ LLViewerInventoryItem *LLViewerInventoryItem::getLinkedItem() const LLViewerInventoryItem *linked_item = gInventory.getItem(mAssetUUID); if (linked_item && linked_item->getIsLinkType()) { - LL_WARNS() << "Warning: Accessing link to link" << LL_ENDL; + LL_WARNS(LOG_INV) << "Warning: Accessing link to link" << LL_ENDL; return NULL; } return linked_item; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 8c9429c05d..10c77da5f3 100755 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2014, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -8258,7 +8258,7 @@ class LLWorldEnableEnvSettings : public view_listener_t } else { - llwarns << "Unknown item" << llendl; + LL_WARNS() << "Unknown time-of-day item: " << tod << LL_ENDL; } } return result; |