summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rwxr-xr-xindra/newview/llappcorehttp.cpp9
-rwxr-xr-xindra/newview/llappcorehttp.h18
-rwxr-xr-xindra/newview/llinventorymodel.cpp601
-rwxr-xr-xindra/newview/llinventorymodel.h82
-rwxr-xr-xindra/newview/llinventorymodelbackgroundfetch.cpp740
-rwxr-xr-xindra/newview/llinventorymodelbackgroundfetch.h28
-rwxr-xr-xindra/newview/llinventoryobserver.cpp3
-rw-r--r--indra/newview/llsnapshotlivepreview.cpp16
-rwxr-xr-xindra/newview/llviewerinventory.cpp128
-rwxr-xr-xindra/newview/llviewermenu.cpp4
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;