summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcorehttp/README.Linden8
-rwxr-xr-xindra/llmessage/CMakeLists.txt4
-rw-r--r--indra/llmessage/llcorehttputil.cpp139
-rw-r--r--indra/llmessage/llcorehttputil.h115
-rwxr-xr-xindra/llmessage/llhttpconstants.cpp6
-rwxr-xr-xindra/llmessage/llhttpconstants.h3
-rwxr-xr-xindra/newview/llappcorehttp.cpp7
-rwxr-xr-xindra/newview/llappcorehttp.h25
-rwxr-xr-xindra/newview/llinventorymodel.cpp629
-rwxr-xr-xindra/newview/llinventorymodel.h82
-rwxr-xr-xindra/newview/llinventorymodelbackgroundfetch.cpp865
-rwxr-xr-xindra/newview/llinventorymodelbackgroundfetch.h28
-rwxr-xr-xindra/newview/llinventoryobserver.cpp3
-rwxr-xr-xindra/newview/llmeshrepository.cpp68
-rw-r--r--indra/newview/llsnapshotlivepreview.cpp2
-rwxr-xr-xindra/newview/lltexturefetch.cpp45
-rwxr-xr-xindra/newview/lltexturefetch.h6
-rwxr-xr-xindra/newview/llviewerinventory.cpp128
-rwxr-xr-xindra/newview/llviewermenu.cpp4
19 files changed, 1503 insertions, 664 deletions
diff --git a/indra/llcorehttp/README.Linden b/indra/llcorehttp/README.Linden
index eb6ccab3bc..c3aaa9158d 100644
--- a/indra/llcorehttp/README.Linden
+++ b/indra/llcorehttp/README.Linden
@@ -529,6 +529,14 @@ HttpOperation::addAsReply: TRACE, ToReplyQueue, Handle: 086D3148
data = NULL;
+ There are now helper functions in llmessage/llcorehttputil.h to
+ assist with LLSD usage. requestPostWithLLSD(...) provides a
+ requestPost()-like interface that takes an LLSD object rather than
+ a BufferArray. And responseToLLSD(...) attempts to convert a
+ BufferArray received from a server into an LLSD object. You can
+ find examples in llmeshrepository.cpp, llinventorymodel.cpp,
+ llinventorymodelbackgroundfetch.cpp and lltexturefetch.cpp.
+
LLSD will often go hand-in-hand with BufferArray and data
transport. But you can also do all the streaming I/O you'd expect
of a std::iostream object:
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index 8bd134dc84..40eddcb0ab 100755
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -6,6 +6,7 @@ include(00-Common)
include(GoogleMock)
include(LLAddBuildTest)
include(LLCommon)
+include(LLCoreHttp)
include(LLMath)
include(LLMessage)
include(LLVFS)
@@ -18,6 +19,7 @@ include_directories (${CMAKE_CURRENT_SOURCE_DIR})
include_directories(
${LLCOMMON_INCLUDE_DIRS}
+ ${LLCOREHTTP_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
@@ -36,6 +38,7 @@ set(llmessage_SOURCE_FILES
llchainio.cpp
llcircuit.cpp
llclassifiedflags.cpp
+ llcorehttputil.cpp
llcurl.cpp
lldatapacker.cpp
lldispatcher.cpp
@@ -124,6 +127,7 @@ set(llmessage_HEADER_FILES
llcipher.h
llcircuit.h
llclassifiedflags.h
+ llcorehttputil.h
llcurl.h
lldatapacker.h
lldbstrings.h
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp
new file mode 100644
index 0000000000..ee80b0fd94
--- /dev/null
+++ b/indra/llmessage/llcorehttputil.cpp
@@ -0,0 +1,139 @@
+/**
+ * @file llcorehttputil.cpp
+ * @date 2014-08-25
+ * @brief Implementation of adapter and utility classes expanding the llcorehttp interfaces.
+ *
+ * $LicenseInfo:firstyear=2014&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include <sstream>
+
+#include "llcorehttputil.h"
+#include "llsdserialize.h"
+
+
+using namespace LLCore;
+
+
+namespace LLCoreHttpUtil
+{
+
+// *TODO: Currently converts only from XML content. A mode
+// to convert using fromBinary() might be useful as well. Mesh
+// headers could use it.
+bool responseToLLSD(HttpResponse * response, bool log, LLSD & out_llsd)
+{
+ // Convert response to LLSD
+ BufferArray * body(response->getBody());
+ if (! body || ! body->size())
+ {
+ return false;
+ }
+
+ LLCore::BufferArrayStream bas(body);
+ LLSD body_llsd;
+ S32 parse_status(LLSDSerialize::fromXML(body_llsd, bas, log));
+ if (LLSDParser::PARSE_FAILURE == parse_status){
+ return false;
+ }
+ out_llsd = body_llsd;
+ return true;
+}
+
+
+HttpHandle requestPostWithLLSD(HttpRequest * request,
+ HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ const LLSD & body,
+ HttpOptions * options,
+ HttpHeaders * headers,
+ HttpHandler * handler)
+{
+ HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+ BufferArray * ba = new BufferArray();
+ BufferArrayStream bas(ba);
+ LLSDSerialize::toXML(body, bas);
+
+ handle = request->requestPost(policy_id,
+ priority,
+ url,
+ ba,
+ options,
+ headers,
+ handler);
+ ba->release();
+ return handle;
+}
+
+
+std::string responseToString(LLCore::HttpResponse * response)
+{
+ static const std::string empty("[Empty]");
+
+ if (! response)
+ {
+ return empty;
+ }
+
+ BufferArray * body(response->getBody());
+ if (! body || ! body->size())
+ {
+ return empty;
+ }
+
+ // Attempt to parse as LLSD regardless of content-type
+ LLSD body_llsd;
+ if (responseToLLSD(response, false, body_llsd))
+ {
+ std::ostringstream tmp;
+
+ LLSDSerialize::toPrettyNotation(body_llsd, tmp);
+ std::size_t temp_len(tmp.tellp());
+
+ if (temp_len)
+ {
+ return tmp.str().substr(0, std::min(temp_len, std::size_t(1024)));
+ }
+ }
+ else
+ {
+ // *TODO: More elaborate forms based on Content-Type as needed.
+ char content[1024];
+
+ size_t len(body->read(0, content, sizeof(content)));
+ if (len)
+ {
+ return std::string(content, 0, len);
+ }
+ }
+
+ // Default
+ return empty;
+}
+
+
+} // end namespace LLCoreHttpUtil
+
diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h
new file mode 100644
index 0000000000..d40172bc7a
--- /dev/null
+++ b/indra/llmessage/llcorehttputil.h
@@ -0,0 +1,115 @@
+/**
+ * @file llcorehttputil.h
+ * @date 2014-08-25
+ * @brief Adapter and utility classes expanding the llcorehttp interfaces.
+ *
+ * $LicenseInfo:firstyear=2014&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLCOREHTTPUTIL_H
+#define LL_LLCOREHTTPUTIL_H
+
+#include <string>
+
+#include "httpcommon.h"
+#include "httprequest.h"
+#include "httpresponse.h"
+#include "httpheaders.h"
+#include "httpoptions.h"
+#include "httphandler.h"
+#include "bufferarray.h"
+#include "bufferstream.h"
+#include "llsd.h"
+
+///
+/// The base llcorehttp library implements many HTTP idioms
+/// used in the viewer but not all. That library intentionally
+/// avoids the use of LLSD and its conventions which aren't
+/// universally applicable. This module, using namespace
+/// LLCoreHttpUtil, provides the additional helper functions
+/// that support idiomatic LLSD transport via the newer
+/// llcorehttp library.
+///
+namespace LLCoreHttpUtil
+{
+
+/// Attempt to convert a response object's contents to LLSD.
+/// It is expected that the response body will be of non-zero
+/// length on input but basic checks will be performed and
+/// and error (false status) returned if there is no data.
+/// If there is data but it cannot be successfully parsed,
+/// an error is also returned. If successfully parsed,
+/// the output LLSD object, out_llsd, is written with the
+/// result and true is returned.
+///
+/// @arg response Response object as returned in
+/// in an HttpHandler onCompleted() callback.
+/// @arg log If true, LLSD parser will emit errors
+/// as LL_INFOS-level messages as it parses.
+/// Otherwise, it *should* be a quiet parse.
+/// @arg out_llsd Output LLSD object written only upon
+/// successful parse of the response object.
+///
+/// @return Returns true (and writes to out_llsd) if
+/// parse was successful. False otherwise.
+///
+bool responseToLLSD(LLCore::HttpResponse * response,
+ bool log,
+ LLSD & out_llsd);
+
+/// Create a std::string representation of a response object
+/// suitable for logging. Mainly intended for logging of
+/// failures and debug information. This won't be fast,
+/// just adequate.
+std::string responseToString(LLCore::HttpResponse * response);
+
+
+/// Issue a standard HttpRequest::requestPost() call but using
+/// and LLSD object as the request body. Conventions are the
+/// same as with that method. Caller is expected to provide
+/// an HttpHeaders object with a correct 'Content-Type:' header.
+/// One will not be provided by this call. You might look after
+/// the 'Accept:' header as well.
+///
+/// @return If request is successfully issued, the
+/// HttpHandle representing the request.
+/// On error, LLCORE_HTTP_HANDLE_INVALID
+/// is returned and caller can fetch detailed
+/// status with the getStatus() method on the
+/// request object. In case of error, no
+/// request is queued and caller may need to
+/// perform additional cleanup such as freeing
+/// a now-useless HttpHandler object.
+///
+LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest * request,
+ LLCore::HttpRequest::policy_t policy_id,
+ LLCore::HttpRequest::priority_t priority,
+ const std::string & url,
+ const LLSD & body,
+ LLCore::HttpOptions * options,
+ LLCore::HttpHeaders * headers,
+ LLCore::HttpHandler * handler);
+
+} // end namespace LLCoreHttpUtil
+
+
+#endif // LL_LLCOREHTTPUTIL_H
diff --git a/indra/llmessage/llhttpconstants.cpp b/indra/llmessage/llhttpconstants.cpp
index 01f4a080b0..32f76f0d70 100755
--- a/indra/llmessage/llhttpconstants.cpp
+++ b/indra/llmessage/llhttpconstants.cpp
@@ -3,11 +3,8 @@
* @brief Implementation of the HTTP request / response constant lookups
*
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
- *
- * Copyright (c) 2013, Linden Research, Inc.
- *
* Second Life Viewer Source Code
- * Copyright (C) 2013, Linden Research, Inc.
+ * Copyright (C) 2013-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
@@ -107,6 +104,7 @@ const std::string HTTP_IN_HEADER_X_FORWARDED_FOR("x-forwarded-for");
const std::string HTTP_CONTENT_LLSD_XML("application/llsd+xml");
const std::string HTTP_CONTENT_OCTET_STREAM("application/octet-stream");
+const std::string HTTP_CONTENT_VND_LL_MESH("application/vnd.ll.mesh");
const std::string HTTP_CONTENT_XML("application/xml");
const std::string HTTP_CONTENT_JSON("application/json");
const std::string HTTP_CONTENT_TEXT_HTML("text/html");
diff --git a/indra/llmessage/llhttpconstants.h b/indra/llmessage/llhttpconstants.h
index 4aa3cc6394..d6bcbd3c19 100755
--- a/indra/llmessage/llhttpconstants.h
+++ b/indra/llmessage/llhttpconstants.h
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2001-2013, Linden Research, Inc.
+ * Copyright (C) 2001-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
@@ -203,6 +203,7 @@ extern const std::string HTTP_IN_HEADER_X_FORWARDED_FOR;
extern const std::string HTTP_CONTENT_LLSD_XML;
extern const std::string HTTP_CONTENT_OCTET_STREAM;
+extern const std::string HTTP_CONTENT_VND_LL_MESH;
extern const std::string HTTP_CONTENT_XML;
extern const std::string HTTP_CONTENT_JSON;
extern const std::string HTTP_CONTENT_TEXT_HTML;
diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp
index e9274c5c1e..f5f224b83e 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"
},
@@ -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..37d7a737e7 100755
--- a/indra/newview/llappcorehttp.h
+++ b/indra/newview/llappcorehttp.h
@@ -64,9 +64,9 @@ 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
+ /// Destination: simhost:12046 & {bake-texture,cdn}:80
/// Protocol: http:
/// Transfer size: KB-MB
/// Long poll: no
@@ -92,9 +92,10 @@ 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
+ /// Destination: simhost:12046 & cdn:80
/// Protocol: http:
/// Transfer size: KB-MB
/// Long poll: no
@@ -112,7 +113,7 @@ public:
/// traffic that can wait for longish stalls
/// (default timeout 600S).
///
- /// Destination: simhost:12046
+ /// Destination: simhost:12046 & cdn:80
/// Protocol: http:
/// Transfer size: MB
/// Long poll: no
@@ -150,6 +151,20 @@ 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_REPORTING = AP_INVENTORY, // Piggy-back on inventory
+
AP_COUNT // Must be last
};
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 14ca0095ae..dab3a4c06d 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 "llcorehttputil.h"
//#define DIFF_INVENTORY_FILES
#ifdef DIFF_INVENTORY_FILES
@@ -67,7 +72,8 @@ 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");
struct InventoryIDPtrLess
{
@@ -125,24 +131,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 +176,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 +283,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 +538,7 @@ public:
protected:
virtual void httpFailure()
{
- LL_WARNS("InvAPI") << dumpResponse() << LL_ENDL;
+ LL_WARNS(LOG_INV) << dumpResponse() << LL_ENDL;
}
virtual void httpSuccess()
@@ -522,7 +552,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 +590,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 +629,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 +850,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 +913,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 +942,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 +956,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 +1030,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 +1092,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 +1138,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 +1201,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 +1210,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 +1218,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 +1241,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 +1251,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 +1259,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 +1347,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 +1385,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 +1416,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 +1426,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 +1461,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 +1471,7 @@ void LLInventoryModel::updateLinkedObjectsFromPurge(const LLUUID &baseobj_id)
if (item_id == baseobj_id) continue;
addChangedMask(LLInventoryObserver::REBUILD, item_id);
}
- gInventory.notifyObservers();
+ notifyObservers();
}
}
@@ -1464,6 +1494,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 +1512,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 +1542,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 +1577,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 +1609,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 +1635,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 +1717,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 +1727,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 +1745,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 +1778,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 +1882,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 +1919,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 +1956,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 +2037,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 +2067,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 +2079,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 +2107,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 +2141,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 +2159,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 +2228,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 +2271,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 +2306,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 +2323,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,8 +2407,80 @@ 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);
+
+ handle = LLCoreHttpUtil::requestPostWithLLSD(request,
+ mHttpPolicyClass,
+ (foreground ? mHttpPriorityFG : mHttpPriorityBG),
+ url,
+ body,
+ mHttpOptions,
+ mHttpHeaders,
+ handler);
+ 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()
@@ -2495,14 +2531,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 +2577,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 +2595,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 +2606,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 +2629,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 +2741,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 +2754,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 +2806,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 +2827,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 +2835,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 +2852,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 +3917,7 @@ bool LLInventoryModel::validate() const
///----------------------------------------------------------------------------
-/*
+#if 0
BOOL decompress_file(const char* src_filename, const char* dst_filename)
{
BOOL rv = FALSE;
@@ -3920,4 +3956,177 @@ BOOL decompress_file(const char* src_filename, const char* dst_filename)
if(dst != NULL) fclose(dst);
return rv;
}
-*/
+#endif
+
+
+///----------------------------------------------------------------------------
+/// Class LLInventoryModel::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)
+{
+ do // Single-pass do-while used for common exit handling
+ {
+ LLCore::HttpStatus status(response->getStatus());
+ // status = LLCore::HttpStatus(404); // Dev tool to force error handling
+ if (! status)
+ {
+ processFailure(status, response);
+ break; // Goto common exit
+ }
+
+ LLCore::BufferArray * body(response->getBody());
+ // body = NULL; // Dev tool to force error handling
+ 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);
+ break; // Goto common exit
+ }
+
+ // body->write(0, "Garbage Response", 16); // Dev tool to force error handling
+ LLSD body_llsd;
+ if (! LLCoreHttpUtil::responseToLLSD(response, true, body_llsd))
+ {
+ // INFOS-level logging will occur on the parsed failure
+ processFailure("HTTP response for inventory item query has malformed LLSD", response);
+ break; // Goto common exit
+ }
+
+ // Expect top-level structure to be a map
+ // body_llsd = LLSD::emptyArray(); // Dev tool to force error handling
+ if (! body_llsd.isMap())
+ {
+ processFailure("LLSD response for inventory item not a map", response);
+ break; // Goto common exit
+ }
+
+ // Check for 200-with-error failures
+ //
+ // Original Responder-based serivce model didn't check for these errors.
+ // It may be more robust to ignore this condition. With aggregated requests,
+ // an error in one inventory item might take down the entire request.
+ // So if this instead broke up the aggregated items into single requests,
+ // maybe that would make progress. Or perhaps there's structured information
+ // that can tell us what went wrong. Need to dig into this and firm up
+ // the API.
+ //
+ // body_llsd["error"] = LLSD::emptyMap(); // Dev tool to force error handling
+ // body_llsd["error"]["identifier"] = "Development";
+ // body_llsd["error"]["message"] = "You left development code in the viewer";
+ if (body_llsd.has("error"))
+ {
+ processFailure("Inventory application error (200-with-error)", response);
+ break; // Goto common exit
+ }
+
+ // Okay, process data if possible
+ processData(body_llsd, response);
+ }
+ while (false);
+
+ // Must delete on completion.
+ delete this;
+}
+
+void LLInventoryModel::FetchItemHttpHandler::processData(LLSD & content, LLCore::HttpResponse * response)
+{
+ 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)
+{
+ const std::string & ct(response->getContentType());
+ LL_WARNS(LOG_INV) << "Inventory item fetch failure\n"
+ << "[Status: " << status.toTerseString() << "]\n"
+ << "[Reason: " << status.toString() << "]\n"
+ << "[Content-type: " << ct << "]\n"
+ << "[Content (abridged): "
+ << LLCoreHttpUtil::responseToString(response) << "]" << LL_ENDL;
+ gInventory.notifyObservers();
+}
+
+void LLInventoryModel::FetchItemHttpHandler::processFailure(const char * const reason, LLCore::HttpResponse * response)
+{
+ LL_WARNS(LOG_INV) << "Inventory item fetch failure\n"
+ << "[Status: internal error]\n"
+ << "[Reason: " << reason << "]\n"
+ << "[Content (abridged): "
+ << LLCoreHttpUtil::responseToString(response) << "]" << 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..f18832fe95 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,180 @@
#include "llviewermessage.h"
#include "llviewerregion.h"
#include "llviewerwindow.h"
+#include "llhttpconstants.h"
+#include "bufferarray.h"
+#include "bufferstream.h"
+#include "llcorehttputil.h"
+
+// History (may be apocryphal)
+//
+// Around V2, an HTTP inventory download mechanism was added
+// along with inventory LINK items referencing other inventory
+// items. As part of this, at login, the entire inventory
+// structure is downloaded 'in the background' using the
+// backgroundFetch()/bulkFetch() methods. The UDP path can
+// still be used and is found in the 'DEPRECATED OLD CODE'
+// section.
+//
+// The old UDP path implemented a throttle that adapted
+// itself during running. The mechanism survived info HTTP
+// somewhat but was pinned to poll the HTTP plumbing at
+// 0.5S intervals. The reasons for this particular value
+// have been lost. It's possible to switch between UDP
+// and HTTP while this is happening but there may be
+// surprises in what happens in that case.
+//
+// Conversion to llcorehttp reduced the number of connections
+// used but batches more data and queues more requests (but
+// doesn't due pipelining due to libcurl restrictions). The
+// poll interval above was re-examined and reduced to get
+// inventory into the viewer more quickly.
+//
+// Possible future work:
+//
+// * Don't download the entire heirarchy in one go (which
+// might have been how V1 worked). Implications for
+// links (which may not have a valid target) and search
+// which would then be missing data.
+//
+// * Review the download rate throttling. Slow then fast?
+// Detect bandwidth usage and speed up when it drops?
+//
+// * A lot of calls to notifyObservers(). It looks like
+// these could be collapsed by maintaining a 'dirty'
+// bit and there appears to be an attempt to do this.
+// But it isn't used or is used in a limited fashion.
+// Are there semanic issues requiring a call after certain
+// updateItem() calls?
+//
+// * An error on a fetch could be due to one item in the batch.
+// If the batch were broken up, perhaps more of the inventory
+// would download. (Handwave here, not certain this is an
+// issue in practice.)
+//
+// * Conversion to AISv3.
+//
+
+
+namespace
+{
+
+///----------------------------------------------------------------------------
+/// Class <anonymous>::BGItemHttpHandler
+///----------------------------------------------------------------------------
+
+//
+// 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.
+//
+// Derives from and is identical to the normal FetchItemHttpHandler
+// except that: 1) it uses the background request object which is
+// updated more slowly than the foreground and 2) keeps a count of
+// active requests on the LLInventoryModelBackgroundFetch object
+// to indicate outstanding operations are in-flight.
+//
+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
+};
+
+
+///----------------------------------------------------------------------------
+/// Class <anonymous>::BGFolderHttpHandler
+///----------------------------------------------------------------------------
+
+// Http request handler class for folders.
+//
+// Handler for FetchInventoryDescendents2 and FetchLibDescendents2
+// caps requests 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");
+
+} // end of namespace anonymous
+
+
+///----------------------------------------------------------------------------
+/// Class LLInventoryModelBackgroundFetch
+///----------------------------------------------------------------------------
+
+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 +240,7 @@ bool LLInventoryModelBackgroundFetch::inventoryFetchCompleted() const
bool LLInventoryModelBackgroundFetch::inventoryFetchInProgress() const
{
- return inventoryFetchStarted() && !inventoryFetchCompleted();
+ return inventoryFetchStarted() && ! inventoryFetchCompleted();
}
bool LLInventoryModelBackgroundFetch::isEverythingFetched() const
@@ -104,24 +253,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 +307,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,11 +333,12 @@ 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;
mBackgroundFetchActive = false;
+ LL_INFOS(LOG_INV) << "Inventory background fetch completed" << LL_ENDL;
}
void LLInventoryModelBackgroundFetch::backgroundFetchCB(void *)
@@ -203,12 +365,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()
// No more categories to fetch, stop fetch process.
if (mFetchQueue.empty())
{
- LL_INFOS() << "Inventory fetch completed" << LL_ENDL;
-
setAllFoldersFetched();
- mBackgroundFetchActive = false;
- mFolderFetchActive = false;
-
return;
}
@@ -219,7 +376,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 +388,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()
break;
}
- if(gDisconnected)
+ if (gDisconnected)
{
// Just bail if we are disconnected.
break;
@@ -292,7 +449,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,258 +512,61 @@ 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;
- }
- }
+ // *TODO: These values could be tweaked at runtime to effect
+ // a fast/slow fetch throttle. Once login is complete and the scene
+ // is mostly loaded, we could turn up the throttle and fill missing
+ // inventory more quickly.
+ static const U32 max_batch_size(10);
+ static const S32 max_concurrent_fetches(12); // Outstanding requests, not connections
+ static const F32 new_min_time(0.05f); // *HACK: Clean this up when old code goes away entirely.
- if (fetcher->isBulkFetchProcessingComplete())
+ mMinTimeBetweenFetches = new_min_time;
+ 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 background 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);
+ // *TODO: Think I'd like to get a shared pointer to this and share it
+ // among all the folder requests.
uuid_vec_t recursive_cats;
LLSD folder_request_body;
@@ -614,27 +574,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 +603,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 +634,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 +662,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 +743,304 @@ bool LLInventoryModelBackgroundFetch::fetchQueueContainsNoDescendentsOf(const LL
}
+namespace
+{
+
+///----------------------------------------------------------------------------
+/// Class <anonymous>::BGFolderHttpHandler
+///----------------------------------------------------------------------------
+
+void BGFolderHttpHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
+{
+ do // Single-pass do-while used for common exit handling
+ {
+ LLCore::HttpStatus status(response->getStatus());
+ // status = LLCore::HttpStatus(404); // Dev tool to force error handling
+ if (! status)
+ {
+ processFailure(status, response);
+ break; // Goto common exit
+ }
+
+ // Response body should be present.
+ LLCore::BufferArray * body(response->getBody());
+ // body = NULL; // Dev tool to force error handling
+ if (! body || ! body->size())
+ {
+ LL_WARNS(LOG_INV) << "Missing data in inventory folder query." << LL_ENDL;
+ processFailure("HTTP response missing expected body", response);
+ break; // Goto common exit
+ }
+
+ // Could test 'Content-Type' header but probably unreliable.
+
+ // Convert response to LLSD
+ // body->write(0, "Garbage Response", 16); // Dev tool to force error handling
+ LLSD body_llsd;
+ if (! LLCoreHttpUtil::responseToLLSD(response, true, body_llsd))
+ {
+ // INFOS-level logging will occur on the parsed failure
+ processFailure("HTTP response contained malformed LLSD", response);
+ break; // goto common exit
+ }
+
+ // Expect top-level structure to be a map
+ // body_llsd = LLSD::emptyArray(); // Dev tool to force error handling
+ if (! body_llsd.isMap())
+ {
+ processFailure("LLSD response not a map", response);
+ break; // goto common exit
+ }
+
+ // Check for 200-with-error failures
+ //
+ // See comments in llinventorymodel.cpp about this mode of error.
+ //
+ // body_llsd["error"] = LLSD::emptyMap(); // Dev tool to force error handling
+ // body_llsd["error"]["identifier"] = "Development";
+ // body_llsd["error"]["message"] = "You left development code in the viewer";
+ if (body_llsd.has("error"))
+ {
+ processFailure("Inventory application error (200-with-error)", response);
+ break; // goto common exit
+ }
+
+ // Okay, process data if possible
+ processData(body_llsd, response);
+ }
+ while (false);
+
+ // Must delete on completion.
+ delete this;
+}
+
+
+void BGFolderHttpHandler::processData(LLSD & content, LLCore::HttpResponse * response)
+{
+ LLInventoryModelBackgroundFetch * fetcher(LLInventoryModelBackgroundFetch::getInstance());
+
+ // API V2 and earlier should probably be testing for "error" map
+ // in response as an application-level error.
+
+ // Instead, we assume success and attempt to extract information.
+ 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 [ed: this isn't 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())
+ {
+ fetcher->setAllFoldersFetched();
+ }
+
+ gInventory.notifyObservers();
+}
+
+
+void BGFolderHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::HttpResponse * response)
+{
+ const std::string & ct(response->getContentType());
+ LL_WARNS(LOG_INV) << "Inventory folder fetch failure\n"
+ << "[Status: " << status.toTerseString() << "]\n"
+ << "[Reason: " << status.toString() << "]\n"
+ << "[Content-type: " << ct << "]\n"
+ << "[Content (abridged): "
+ << LLCoreHttpUtil::responseToString(response) << "]" << LL_ENDL;
+
+ // Could use a 404 test here to try to detect revoked caps...
+
+ // This was originally the request retry logic for the inventory
+ // request which tested on HTTP_INTERNAL_ERROR status. This
+ // retry logic was unbounded and lacked discrimination as to the
+ // cause of the retry. The new http library should be doing
+ // adquately on retries but I want to keep the structure of a
+ // retry for reference.
+ LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
+ if (false)
+ {
+ // 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"].asUUID());
+ 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) << "Inventory folder fetch failure\n"
+ << "[Status: internal error]\n"
+ << "[Reason: " << reason << "]\n"
+ << "[Content (abridged): "
+ << LLCoreHttpUtil::responseToString(response) << "]" << LL_ENDL;
+
+ // Reverse of previous processFailure() method, this is invoked
+ // when response structure is found to be invalid. Original
+ // always re-issued the request (without limit). This does
+ // the same but be aware that this may be a source of problems.
+ // Philosophy is that inventory folders are so essential to
+ // operation that this is a reasonable action.
+ LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
+ if (true)
+ {
+ 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"].asUUID());
+ 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();
+}
+
+///----------------------------------------------------------------------------
+/// Class <anonymous>::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/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index a6707392fe..648056484e 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -71,6 +71,7 @@
#include "bufferarray.h"
#include "bufferstream.h"
#include "llfasttimer.h"
+#include "llcorehttputil.h"
#include "boost/lexical_cast.hpp"
@@ -759,7 +760,7 @@ LLMeshRepoThread::LLMeshRepoThread()
mHttpLargeOptions->setTransferTimeout(LARGE_MESH_XFER_TIMEOUT);
mHttpLargeOptions->setUseRetryAfter(gSavedSettings.getBOOL("MeshUseHttpRetryAfter"));
mHttpHeaders = new LLCore::HttpHeaders;
- mHttpHeaders->append("Accept", "application/vnd.ll.mesh");
+ mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_VND_LL_MESH);
mHttpPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_MESH2);
mHttpLegacyPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_MESH1);
mHttpLargePolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_LARGE_MESH);
@@ -1886,7 +1887,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,
mHttpOptions->setUseRetryAfter(gSavedSettings.getBOOL("MeshUseHttpRetryAfter"));
mHttpOptions->setRetries(UPLOAD_RETRY_LIMIT);
mHttpHeaders = new LLCore::HttpHeaders;
- mHttpHeaders->append("Content-Type", "application/llsd+xml");
+ mHttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_UPLOADS);
mHttpPriority = 0;
}
@@ -2236,21 +2237,17 @@ void LLMeshUploadThread::doWholeModelUpload()
mModelData = LLSD::emptyMap();
wholeModelToLLSD(mModelData, true);
LLSD body = mModelData["asset_resources"];
- dump_llsd_to_file(body,make_dump_name("whole_model_body_",dump_num));
-
- LLCore::BufferArray * ba = new LLCore::BufferArray;
- LLCore::BufferArrayStream bas(ba);
- LLSDSerialize::toXML(body, bas);
- // LLSDSerialize::toXML(mModelData, bas); // <- Enabling this will generate a convenient upload error
- LLCore::HttpHandle handle = mHttpRequest->requestPost(mHttpPolicyClass,
- mHttpPriority,
- mWholeModelUploadURL,
- ba,
- mHttpOptions,
- mHttpHeaders,
- this);
- ba->release();
-
+
+ dump_llsd_to_file(body, make_dump_name("whole_model_body_", dump_num));
+
+ LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest,
+ mHttpPolicyClass,
+ mHttpPriority,
+ mWholeModelUploadURL,
+ body,
+ mHttpOptions,
+ mHttpHeaders,
+ this);
if (LLCORE_HTTP_HANDLE_INVALID == handle)
{
mHttpStatus = mHttpRequest->getStatus();
@@ -2294,19 +2291,14 @@ void LLMeshUploadThread::requestWholeModelFee()
mModelData = LLSD::emptyMap();
wholeModelToLLSD(mModelData, false);
dump_llsd_to_file(mModelData, make_dump_name("whole_model_fee_request_", dump_num));
-
- LLCore::BufferArray * ba = new LLCore::BufferArray;
- LLCore::BufferArrayStream bas(ba);
- LLSDSerialize::toXML(mModelData, bas);
-
- LLCore::HttpHandle handle = mHttpRequest->requestPost(mHttpPolicyClass,
- mHttpPriority,
- mWholeModelFeeCapability,
- ba,
- mHttpOptions,
- mHttpHeaders,
- this);
- ba->release();
+ LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest,
+ mHttpPolicyClass,
+ mHttpPriority,
+ mWholeModelFeeCapability,
+ mModelData,
+ mHttpOptions,
+ mHttpHeaders,
+ this);
if (LLCORE_HTTP_HANDLE_INVALID == handle)
{
mHttpStatus = mHttpRequest->getStatus();
@@ -2379,12 +2371,8 @@ void LLMeshUploadThread::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResp
}
else
{
- LLCore::BufferArray * ba(response->getBody());
- if (ba && ba->size())
- {
- LLCore::BufferArrayStream bas(ba);
- LLSDSerialize::fromXML(body, bas);
- }
+ // *TODO: handle error in conversion process
+ LLCoreHttpUtil::responseToLLSD(response, true, body);
}
dump_llsd_to_file(body, make_dump_name("whole_model_upload_response_", dump_num));
@@ -2443,12 +2431,8 @@ void LLMeshUploadThread::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResp
}
else
{
- LLCore::BufferArray * ba(response->getBody());
- if (ba && ba->size())
- {
- LLCore::BufferArrayStream bas(ba);
- LLSDSerialize::fromXML(body, bas);
- }
+ // *TODO: handle error in conversion process
+ LLCoreHttpUtil::responseToLLSD(response, true, body);
}
dump_llsd_to_file(body, make_dump_name("whole_model_fee_response_", dump_num));
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index 1aa7041175..600ebf5914 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
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index a64a6ee091..acd4cf2d8d 100755
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -56,13 +56,13 @@
#include "llsdparam.h"
#include "llsdutil.h"
#include "llstartup.h"
-#include "llsdserialize.h"
#include "httprequest.h"
#include "httphandler.h"
#include "httpresponse.h"
#include "bufferarray.h"
#include "bufferstream.h"
+#include "llcorehttputil.h"
#include "llhttpretrypolicy.h"
@@ -1349,20 +1349,20 @@ bool LLTextureFetchWorker::doWork(S32 param)
LL_WARNS(LOG_TXT) << "trying to seek a non-default texture on the sim. Bad!" << LL_ENDL;
}
setUrl(http_url + "/?texture_id=" + mID.asString().c_str());
- LL_DEBUGS("Texture") << "Texture URL " << mUrl << LL_ENDL;
+ LL_DEBUGS(LOG_TXT) << "Texture URL: " << mUrl << LL_ENDL;
mWriteToCacheState = CAN_WRITE ; //because this texture has a fixed texture id.
}
else
{
mCanUseHTTP = false ;
- LL_DEBUGS("Texture") << "Texture not available via HTTP: no URL " << mUrl << LL_ENDL;
+ LL_DEBUGS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
}
}
else
{
// This will happen if not logged in or if a region deoes not have HTTP Texture enabled
//LL_WARNS(LOG_TXT) << "Region not found for host: " << mHost << LL_ENDL;
- LL_DEBUGS("Texture") << "Texture not available via HTTP: no region " << mUrl << LL_ENDL;
+ LL_DEBUGS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL;
mCanUseHTTP = false;
}
}
@@ -2514,8 +2514,9 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
mHttpOptions(NULL),
mHttpOptionsWithHeaders(NULL),
mHttpHeaders(NULL),
- mHttpMetricsHeaders(NULL),
mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
+ mHttpMetricsHeaders(NULL),
+ mHttpMetricsPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
mTotalCacheReadCount(0U),
mTotalCacheWriteCount(0U),
mTotalResourceWaitCount(0U),
@@ -2528,15 +2529,16 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), U32Bytes(gSavedSettings.getU32("TextureLoggingThreshold")));
LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
- mHttpPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_TEXTURE);
mHttpRequest = new LLCore::HttpRequest;
mHttpOptions = new LLCore::HttpOptions;
mHttpOptionsWithHeaders = new LLCore::HttpOptions;
mHttpOptionsWithHeaders->setWantHeaders(true);
mHttpHeaders = new LLCore::HttpHeaders;
- mHttpHeaders->append("Accept", "image/x-j2c");
+ mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_IMAGE_X_J2C);
+ mHttpPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_TEXTURE);
mHttpMetricsHeaders = new LLCore::HttpHeaders;
- mHttpMetricsHeaders->append("Content-Type", "application/llsd+xml");
+ mHttpMetricsHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
+ mHttpMetricsPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_REPORTING);
mHttpHighWater = HTTP_NONPIPE_REQUESTS_HIGH_WATER;
mHttpLowWater = HTTP_NONPIPE_REQUESTS_LOW_WATER;
mHttpSemaphore = 0;
@@ -4026,7 +4028,9 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
// Update sequence number
if (S32_MAX == ++report_sequence)
+ {
report_sequence = 0;
+ }
reporting_started = true;
// Limit the size of the stats report if necessary.
@@ -4035,18 +4039,15 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
if (! mCapsURL.empty())
{
- LLCore::BufferArray * ba = new LLCore::BufferArray;
- LLCore::BufferArrayStream bas(ba);
- LLSDSerialize::toXML(sd, bas);
-
- fetcher->getHttpRequest().requestPost(fetcher->getPolicyClass(),
- report_priority,
- mCapsURL,
- ba,
- NULL,
- fetcher->getMetricsHeaders(),
- handler);
- ba->release();
+ // Don't care about handle, this is a fire-and-forget operation.
+ LLCoreHttpUtil::requestPostWithLLSD(&fetcher->getHttpRequest(),
+ fetcher->getMetricsPolicyClass(),
+ report_priority,
+ mCapsURL,
+ sd,
+ NULL,
+ fetcher->getMetricsHeaders(),
+ handler);
LLTextureFetch::svMetricsDataBreak = false;
}
else
@@ -4057,7 +4058,7 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
// In QA mode, Metrics submode, log the result for ease of testing
if (fetcher->isQAMode())
{
- LL_INFOS("Textures") << ll_pretty_print_sd(sd) << LL_ENDL;
+ LL_INFOS(LOG_TXT) << ll_pretty_print_sd(sd) << LL_ENDL;
}
return true;
@@ -4227,7 +4228,7 @@ void LLTextureFetchDebugger::init()
if (! mHttpHeaders)
{
mHttpHeaders = new LLCore::HttpHeaders;
- mHttpHeaders->append("Accept", "image/x-j2c");
+ mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_IMAGE_X_J2C);
}
}
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index 89d18e2c67..27779a31e0 100755
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -179,6 +179,9 @@ public:
// Threads: T*
LLCore::HttpHeaders * getMetricsHeaders() const { return mHttpMetricsHeaders; }
+ // Threads: T*
+ LLCore::HttpRequest::policy_t getMetricsPolicyClass() const { return mHttpMetricsPolicyClass; }
+
bool isQAMode() const { return mQAMode; }
// ----------------------------------
@@ -354,8 +357,9 @@ private:
LLCore::HttpOptions * mHttpOptions; // Ttf
LLCore::HttpOptions * mHttpOptionsWithHeaders; // Ttf
LLCore::HttpHeaders * mHttpHeaders; // Ttf
- LLCore::HttpHeaders * mHttpMetricsHeaders; // Ttf
LLCore::HttpRequest::policy_t mHttpPolicyClass; // T*
+ LLCore::HttpHeaders * mHttpMetricsHeaders; // Ttf
+ LLCore::HttpRequest::policy_t mHttpMetricsPolicyClass; // T*
S32 mHttpHighWater; // Ttf
S32 mHttpLowWater; // Ttf
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 38aaff9279..faf929d8f9 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
@@ -8287,7 +8287,7 @@ class LLWorldEnableEnvSettings : public view_listener_t
}
else
{
- llwarns << "Unknown item" << llendl;
+ LL_WARNS() << "Unknown time-of-day item: " << tod << LL_ENDL;
}
}
return result;