From 580f9088b4644c1d9e41a25deac42dc487e9d5c1 Mon Sep 17 00:00:00 2001
From: Dave Simmons <simon@lindenlab.com>
Date: Wed, 25 Jun 2008 16:22:00 +0000
Subject: [PATCH] svn merge -r90394:90492 svn/branches/havok4/qar-689 -->
 release QAR-689 - branch/havok4/havok4-7 r89805 is ready for merge back into
 release

---
 indra/llcommon/indra_constants.h     |   2 +-
 indra/llcommon/llsdserialize.cpp     |  25 ++++--
 indra/llcommon/llsdserialize.h       |  41 ++++++++-
 indra/llcommon/llsdserialize_xml.cpp | 128 ++++++++++++++++++++++-----
 indra/llcommon/llstat.cpp            |   5 +-
 indra/llcommon/llstat.h              |   8 +-
 indra/llmath/v3math.cpp              |  66 ++++++++++++++
 indra/llmath/v3math.h                |   1 +
 indra/llmessage/llassetstorage.cpp   |  66 +++++++++++++-
 indra/llmessage/llassetstorage.h     |  15 +++-
 indra/newview/llviewerregion.cpp     |   2 +-
 11 files changed, 321 insertions(+), 38 deletions(-)

diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h
index 5697fb9f41d..e83da12beb7 100644
--- a/indra/llcommon/indra_constants.h
+++ b/indra/llcommon/indra_constants.h
@@ -78,7 +78,7 @@ enum LAND_STAT_REPORT_TYPE
 const U32 STAT_FILTER_MASK	= 0x1FFFFFFF;
 
 // Default maximum number of tasks/prims per region.
-const U32 MAX_TASKS_PER_REGION = 15000;
+const U32 DEFAULT_MAX_REGION_WIDE_PRIM_COUNT = 15000;
 
 const 	F32 	MIN_AGENT_DEPTH			= 0.30f;
 const 	F32 	DEFAULT_AGENT_DEPTH 	= 0.45f;
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 2183792bb1b..6bb75439a2b 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -146,12 +146,15 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, S32 max_bytes)
 	 * Create the parser as appropriate
 	 */
 	if (legacy_no_header)
-	{
-		LLSDXMLParser* x = new LLSDXMLParser;
-		x->parsePart(hdr_buf, inbuf);
-		p = x;
+	{	// Create a LLSD XML parser, and parse the first chunk read above
+		LLSDXMLParser* x = new LLSDXMLParser();
+		x->parsePart(hdr_buf, inbuf);	// Parse the first part that was already read
+		x->parseLines(str, sd);			// Parse the rest of it
+		delete x;
+		return true;
 	}
-	else if (header == LLSD_BINARY_HEADER)
+
+	if (header == LLSD_BINARY_HEADER)
 	{
 		p = new LLSDBinaryParser;
 	}
@@ -300,7 +303,8 @@ static const char BINARY_FALSE_SERIAL = '0';
 /**
  * LLSDParser
  */
-LLSDParser::LLSDParser() : mCheckLimits(true), mMaxBytesLeft(0)
+LLSDParser::LLSDParser()
+	: mCheckLimits(true), mMaxBytesLeft(0), mParseLines(false)
 {
 }
 
@@ -316,6 +320,15 @@ S32 LLSDParser::parse(std::istream& istr, LLSD& data, S32 max_bytes)
 }
 
 
+// Parse using routine to get() lines, faster than parse()
+S32 LLSDParser::parseLines(std::istream& istr, LLSD& data)
+{
+	mCheckLimits = false;
+	mParseLines = true;
+	return doParse(istr, data);
+}
+
+
 int LLSDParser::get(std::istream& istr) const
 {
 	if(mCheckLimits) --mMaxBytesLeft;
diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h
index 5e880701302..df78bb44f4f 100644
--- a/indra/llcommon/llsdserialize.h
+++ b/indra/llcommon/llsdserialize.h
@@ -83,6 +83,18 @@ class LLSDParser : public LLRefCount
 	 */
 	S32 parse(std::istream& istr, LLSD& data, S32 max_bytes);
 
+	/** Like parse(), but uses a different call (istream.getline()) to read by lines
+	 *  This API is better suited for XML, where the parse cannot tell
+	 *  where the document actually ends.
+	 */
+	S32 parseLines(std::istream& istr, LLSD& data);
+
+	/** 
+	 * @brief Resets the parser so parse() or parseLines() can be called again for another <llsd> chunk.
+	 */
+	void reset()	{ doReset();	};
+
+
 protected:
 	/** 
 	 * @brief Pure virtual base for doing the parse.
@@ -100,6 +112,11 @@ class LLSDParser : public LLRefCount
 	 */
 	virtual S32 doParse(std::istream& istr, LLSD& data) const = 0;
 
+	/** 
+	 * @brief Virtual default function for resetting the parser
+	 */
+	virtual void doReset()	{};
+
 	/* @name Simple istream helper methods 
 	 *
 	 * These helper methods exist to help correctly use the
@@ -191,6 +208,11 @@ class LLSDParser : public LLRefCount
 	 * @brief The maximum number of bytes left to be parsed.
 	 */
 	mutable S32 mMaxBytesLeft;
+	
+	/**
+	 * @brief Use line-based reading to get text
+	 */
+	bool mParseLines;
 };
 
 /** 
@@ -301,6 +323,11 @@ class LLSDXMLParser : public LLSDParser
 	 */
 	virtual S32 doParse(std::istream& istr, LLSD& data) const;
 
+	/** 
+	 * @brief Virtual default function for resetting the parser
+	 */
+	virtual void doReset();
+
 private:
 	class Impl;
 	Impl& impl;
@@ -674,7 +701,7 @@ class LLSDSerialize
 		U32 options = LLSDFormatter::OPTIONS_NONE);
 
 	/**
-	 * @breif Examine a stream, and parse 1 sd object out based on contents.
+	 * @brief Examine a stream, and parse 1 sd object out based on contents.
 	 *
 	 * @param sd [out] The data found on the stream
 	 * @param str The incoming stream
@@ -718,13 +745,23 @@ class LLSDSerialize
 		return f->format(sd, str, LLSDFormatter::OPTIONS_PRETTY);
 	}
 
-	static S32 fromXML(LLSD& sd, std::istream& str)
+	static S32 fromXMLEmbedded(LLSD& sd, std::istream& str)
 	{
 		// no need for max_bytes since xml formatting is not
 		// subvertable by bad sizes.
 		LLPointer<LLSDXMLParser> p = new LLSDXMLParser;
 		return p->parse(str, sd, LLSDSerialize::SIZE_UNLIMITED);
 	}
+	static S32 fromXMLDocument(LLSD& sd, std::istream& str)
+	{
+		LLPointer<LLSDXMLParser> p = new LLSDXMLParser();
+		return p->parseLines(str, sd);
+	}
+	static S32 fromXML(LLSD& sd, std::istream& str)
+	{
+		return fromXMLEmbedded(sd, str);
+//		return fromXMLDocument(sd, str);
+	}
 
 	/*
 	 * Binary Methods
diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp
index cddb243faf9..592dfc9bc09 100644
--- a/indra/llcommon/llsdserialize_xml.cpp
+++ b/indra/llcommon/llsdserialize_xml.cpp
@@ -262,12 +262,13 @@ class LLSDXMLParser::Impl
 	~Impl();
 	
 	S32 parse(std::istream& input, LLSD& data);
+	S32 parseLines(std::istream& input, LLSD& data);
 
 	void parsePart(const char *buf, int len);
 	
-private:
 	void reset();
-	
+
+private:
 	void startElementHandler(const XML_Char* name, const XML_Char** attributes);
 	void endElementHandler(const XML_Char* name);
 	void characterDataHandler(const XML_Char* data, int length);
@@ -307,8 +308,8 @@ class LLSDXMLParser::Impl
 	LLSD mResult;
 	S32 mParseCount;
 	
-	bool mInLLSDElement;
-	bool mGracefullStop;
+	bool mInLLSDElement;			// true if we're on LLSD
+	bool mGracefullStop;			// true if we found the </llsd
 	
 	typedef std::deque<LLSD*> LLSDRefStack;
 	LLSDRefStack mStack;
@@ -319,15 +320,12 @@ class LLSDXMLParser::Impl
 	
 	std::string mCurrentKey;
 	std::ostringstream mCurrentContent;
-
-	bool mPreStaged;
 };
 
 
 LLSDXMLParser::Impl::Impl()
 {
 	mParser = XML_ParserCreate(NULL);
-	mPreStaged = false;
 	reset();
 }
 
@@ -336,7 +334,7 @@ LLSDXMLParser::Impl::~Impl()
 	XML_ParserFree(mParser);
 }
 
-bool is_eol(char c)
+inline bool is_eol(char c)
 {
 	return (c == '\n' || c == '\r');
 }
@@ -356,9 +354,9 @@ static unsigned get_till_eol(std::istream& input, char *buf, unsigned bufsize)
 	unsigned count = 0;
 	while (count < bufsize && input.good())
 	{
-		input.get(buf[count]);
-		count++;
-		if (is_eol(buf[count - 1]))
+		char c = input.get();
+		buf[count++] = c;
+		if (is_eol(c))
 			break;
 	}
 	return count;
@@ -366,7 +364,6 @@ static unsigned get_till_eol(std::istream& input, char *buf, unsigned bufsize)
 
 S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)
 {
-	reset();
 	XML_Status status;
 	
 	static const int BUFFER_SIZE = 1024;
@@ -420,14 +417,86 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)
 	return mParseCount;
 }
 
-void LLSDXMLParser::Impl::reset()
+
+S32 LLSDXMLParser::Impl::parseLines(std::istream& input, LLSD& data)
 {
-	if (mPreStaged)
+	XML_Status status = XML_STATUS_OK;
+
+	data = LLSD();
+
+	static const int BUFFER_SIZE = 1024;
+
+	//static char last_buffer[ BUFFER_SIZE ];
+	//std::streamsize last_num_read;
+
+	// Must get rid of any leading \n, otherwise the stream gets into an error/eof state
+	clear_eol(input);
+
+	while( !mGracefullStop
+		&& input.good() 
+		&& !input.eof())
 	{
-		mPreStaged = false;
-		return;
+		void* buffer = XML_GetBuffer(mParser, BUFFER_SIZE);
+		/*
+		 * If we happened to end our last buffer right at the end of the llsd, but the
+		 * stream is still going we will get a null buffer here.  Check for mGracefullStop.
+		 * -- I don't think this is actually true - zero 2008-05-09
+		 */
+		if (!buffer)
+		{
+			break;
+		}
+		
+		// Get one line
+		input.getline((char*)buffer, BUFFER_SIZE);
+		std::streamsize num_read = input.gcount();
+
+		//memcpy( last_buffer, buffer, num_read );
+		//last_num_read = num_read;
+
+		if ( num_read > 0 )
+		{
+			if (!input.good() )
+			{	// Clear state that's set when we run out of buffer
+				input.clear();
+			}
+		
+			// Don't parse the NULL at the end which might be added if \n was absorbed by getline()
+			char * text = (char *) buffer;
+			if ( text[num_read - 1] == 0)
+			{
+				num_read--;
+			}
+		}
+
+		status = XML_ParseBuffer(mParser, num_read, false);
+		if (status == XML_STATUS_ERROR)
+		{
+			break;
+		}
+	}
+
+	if (status != XML_STATUS_ERROR
+		&& !mGracefullStop)
+	{	// Parse last bit
+		status = XML_ParseBuffer(mParser, 0, true);
+	}
+	
+	if (status == XML_STATUS_ERROR  
+		&& !mGracefullStop)
+	{
+		llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl;
+		return LLSDParser::PARSE_FAILURE;
 	}
 
+	clear_eol(input);
+	data = mResult;
+	return mParseCount;
+}
+
+
+void LLSDXMLParser::Impl::reset()
+{
 	mResult.clear();
 	mParseCount = 0;
 
@@ -476,14 +545,15 @@ LLSDXMLParser::Impl::findAttribute(const XML_Char* name, const XML_Char** pairs)
 
 void LLSDXMLParser::Impl::parsePart(const char* buf, int len)
 {
-	void * buffer = XML_GetBuffer(mParser, len);
-	if (buffer != NULL && buf != NULL)
+	if ( buf != NULL 
+		&& len > 0 )
 	{
-		memcpy(buffer, buf, len);
+		XML_Status status = XML_Parse(mParser, buf, len, false);
+		if (status == XML_STATUS_ERROR)
+		{
+			llinfos << "Unexpected XML parsing error at start" << llendl;
+		}
 	}
-	XML_ParseBuffer(mParser, len, false);
-
-	mPreStaged = true;
 }
 
 void LLSDXMLParser::Impl::startElementHandler(const XML_Char* name, const XML_Char** attributes)
@@ -738,5 +808,17 @@ void LLSDXMLParser::parsePart(const char *buf, int len)
 // virtual
 S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data) const
 {
-	return impl.parse(input, data);	
+	if (mParseLines)
+	{
+		// Use line-based reading (faster code)
+		return impl.parseLines(input, data);
+	}
+
+	return impl.parse(input, data);
+}
+
+//	virtual 
+void LLSDXMLParser::doReset()
+{
+	impl.reset();
 }
diff --git a/indra/llcommon/llstat.cpp b/indra/llcommon/llstat.cpp
index e999934b628..21b723de71c 100644
--- a/indra/llcommon/llstat.cpp
+++ b/indra/llcommon/llstat.cpp
@@ -76,10 +76,11 @@ class LLStatAccum::impl
 
 U64 LLStatAccum::impl::sScaleTimes[IMPL_NUM_SCALES] =
 {
+	USEC_PER_SEC / 10,				// 100 millisec
 	USEC_PER_SEC * 1,				// seconds
 	USEC_PER_SEC * 60,				// minutes
-	USEC_PER_SEC * 60 * 2				// minutes
-#if 0
+	USEC_PER_SEC * 60 * 2			// two minutes
+#if ENABLE_LONG_TIME_STATS
 	// enable these when more time scales are desired
 	USEC_PER_SEC * 60*60,			// hours
 	USEC_PER_SEC * 24*60*60,		// days
diff --git a/indra/llcommon/llstat.h b/indra/llcommon/llstat.h
index e20c01f67fa..5fa46fca75c 100644
--- a/indra/llcommon/llstat.h
+++ b/indra/llcommon/llstat.h
@@ -37,6 +37,9 @@
 #include "lltimer.h"
 #include "llframetimer.h"
 
+// Set this if longer stats are needed
+#define ENABLE_LONG_TIME_STATS	0
+
 //
 // Accumulates statistics for an arbitrary length of time.
 // Does this by maintaining a chain of accumulators, each one
@@ -52,19 +55,22 @@ class LLStatAccum
 
 public:
 	enum TimeScale {
+		SCALE_100MS,
 		SCALE_SECOND,
 		SCALE_MINUTE,
 		SCALE_TWO_MINUTE,
+#if ENABLE_LONG_TIME_STATS
 		SCALE_HOUR,
 		SCALE_DAY,
 		SCALE_WEEK,
-
+#endif
 		NUM_SCALES
 	};
 
 	F32 meanValue(TimeScale scale) const;
 		// see the subclasses for the specific meaning of value
 
+	F32 meanValueOverLast100ms()  const { return meanValue(SCALE_100MS);  }
 	F32 meanValueOverLastSecond() const	{ return meanValue(SCALE_SECOND); }
 	F32 meanValueOverLastMinute() const	{ return meanValue(SCALE_MINUTE); }
 
diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp
index f1fe1a780ef..6299bbd1b74 100644
--- a/indra/llmath/v3math.cpp
+++ b/indra/llmath/v3math.cpp
@@ -73,6 +73,72 @@ BOOL LLVector3::clamp(F32 min, F32 max)
 	return ret;
 }
 
+// Clamps length to an upper limit.  
+// Returns TRUE if the data changed
+BOOL LLVector3::clampLength( F32 length_limit )
+{
+	BOOL changed = FALSE;
+
+	F32 len = length();
+	if (llfinite(len))
+	{
+		if ( len > length_limit)
+		{
+			normalize();
+			if (length_limit < 0.f)
+			{
+				length_limit = 0.f;
+			}
+			mV[0] *= length_limit;
+			mV[1] *= length_limit;
+			mV[2] *= length_limit;
+			changed = TRUE;
+		}
+	}
+	else
+	{	// this vector may still be salvagable
+		F32 max_abs_component = 0.f;
+		for (S32 i = 0; i < 3; ++i)
+		{
+			F32 abs_component = fabs(mV[i]);
+			if (llfinite(abs_component))
+			{
+				if (abs_component > max_abs_component)
+				{
+					max_abs_component = abs_component;
+				}
+			}
+			else
+			{
+				// no it can't be salvaged --> clear it
+				clear();
+				changed = TRUE;
+				break;
+			}
+		}
+		if (!changed)
+		{
+			// yes it can be salvaged -->
+			// bring the components down before we normalize
+			mV[0] /= max_abs_component;
+			mV[1] /= max_abs_component;
+			mV[2] /= max_abs_component;
+			normalize();
+
+			if (length_limit < 0.f)
+			{
+				length_limit = 0.f;
+			}
+			mV[0] *= length_limit;
+			mV[1] *= length_limit;
+			mV[2] *= length_limit;
+		}
+	}
+
+	return changed;
+}
+
+
 // Sets all values to absolute value of their original values
 // Returns TRUE if data changed
 BOOL LLVector3::abs()
diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h
index 03c780a1f44..d8f3bec1931 100644
--- a/indra/llmath/v3math.h
+++ b/indra/llmath/v3math.h
@@ -74,6 +74,7 @@ class LLVector3
 
 		inline BOOL isFinite() const;									// checks to see if all values of LLVector3 are finite
 		BOOL		clamp(F32 min, F32 max);		// Clamps all values to (min,max), returns TRUE if data changed
+		BOOL		clampLength( F32 length_limit );					// Scales vector to limit length to a value
 
 		void		quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz);	// changes the vector to reflect quatization
 		void		quantize8(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz);	// changes the vector to reflect quatization
diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp
index 2c8e7ce8a64..9d32afc2f0f 100644
--- a/indra/llmessage/llassetstorage.cpp
+++ b/indra/llmessage/llassetstorage.cpp
@@ -42,6 +42,7 @@
 #include "llstring.h"
 #include "lldir.h"
 #include "llsd.h"
+#include "llframetimer.h"
 
 // this library includes
 #include "message.h"
@@ -60,6 +61,9 @@ LLMetrics *LLAssetStorage::metric_recipient = NULL;
 
 const LLUUID CATEGORIZE_LOST_AND_FOUND_ID("00000000-0000-0000-0000-000000000010");
 
+const U64 TOXIC_ASSET_LIFETIME = (120 * 1000000);		// microseconds
+
+
 ///----------------------------------------------------------------------------
 /// LLAssetInfo
 ///----------------------------------------------------------------------------
@@ -314,6 +318,9 @@ LLAssetStorage::~LLAssetStorage()
 		// unregister our callbacks with the message system
 		gMessageSystem->setHandlerFuncFast(_PREHASH_AssetUploadComplete, NULL, NULL);
 	}
+
+	// Clear the toxic asset map
+	mToxicAssetMap.clear();
 }
 
 void LLAssetStorage::setUpstream(const LLHost &upstream_host)
@@ -1233,7 +1240,11 @@ void LLAssetStorage::legacyGetDataCallback(LLVFS *vfs, const LLUUID &uuid, LLAss
 	LLLegacyAssetRequest *legacy = (LLLegacyAssetRequest *)user_data;
 	char filename[LL_MAX_PATH] = "";	/* Flawfinder: ignore */ 
 
-	if (! status)
+	// Check if the asset is marked toxic, and don't load bad stuff
+	BOOL toxic = gAssetStorage->isAssetToxic( uuid );
+
+	if ( !status
+		&& !toxic )
 	{
 		LLVFile file(vfs, uuid, type);
 
@@ -1431,3 +1442,56 @@ void LLAssetStorage::reportMetric( const LLUUID& asset_id, const LLAssetType::ET
 		metric_recipient->recordEvent(metric_name, message, success);
 	}
 }
+
+
+// Check if an asset is in the toxic map.  If it is, the entry is updated
+BOOL	LLAssetStorage::isAssetToxic( const LLUUID& uuid )
+{
+	BOOL is_toxic = FALSE;
+
+	if ( !uuid.isNull() )
+	{
+		toxic_asset_map_t::iterator iter = mToxicAssetMap.find( uuid );
+		if ( iter != mToxicAssetMap.end() )
+		{	// Found toxic asset
+			(*iter).second = LLFrameTimer::getTotalTime() + TOXIC_ASSET_LIFETIME;
+			is_toxic = TRUE;
+		} 
+	}
+	return is_toxic;
+}
+
+
+
+
+// Clean the toxic asset list, remove old entries
+void	LLAssetStorage::flushOldToxicAssets( BOOL force_it )
+{
+	// Scan and look for old entries
+	U64 now = LLFrameTimer::getTotalTime();
+	toxic_asset_map_t::iterator iter = mToxicAssetMap.begin();
+	while ( iter != mToxicAssetMap.end() )
+	{
+		if ( force_it
+			|| (*iter).second < now )
+		{	// Too old - remove it
+			mToxicAssetMap.erase( iter++ );
+		}
+		else
+		{
+			iter++;
+		}
+	}
+}
+
+
+// Add an item to the toxic asset map
+void	LLAssetStorage::markAssetToxic( const LLUUID& uuid )
+{	
+	if ( !uuid.isNull() )
+	{
+		// Set the value to the current time.  Creates a new entry if needed
+		mToxicAssetMap[ uuid ] = LLFrameTimer::getTotalTime() + TOXIC_ASSET_LIFETIME;
+	}
+}
+
diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h
index 8da3926c639..b1007e83c65 100644
--- a/indra/llmessage/llassetstorage.h
+++ b/indra/llmessage/llassetstorage.h
@@ -197,7 +197,8 @@ class LLEstateAssetRequest
 };
 
 
-
+// Map of known bad assets
+typedef std::map<LLUUID,U64,lluuid_less> toxic_asset_map_t;
 
 typedef void (*LLGetAssetCallback)(LLVFS *vfs, const LLUUID &asset_id,
 										 LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status);
@@ -231,6 +232,9 @@ class LLAssetStorage
 	request_list_t mPendingUploads;
 	request_list_t mPendingLocalUploads;
 	
+	// Map of toxic assets - these caused problems when recently rezzed, so avoid them
+	toxic_asset_map_t	mToxicAssetMap;		// Objects in this list are known to cause problems and are not loaded
+
 public:
 	LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
 				   LLVFS *vfs, const LLHost &upstream_host);
@@ -291,6 +295,15 @@ class LLAssetStorage
 						 const LLUUID &asset_id, LLAssetType::EType atype,
 						 LLGetAssetCallback cb, void *user_data, BOOL is_priority = FALSE); // Get a particular inventory item.
 
+	// Check if an asset is in the toxic map.  If it is, the entry is updated
+	BOOL		isAssetToxic( const LLUUID& uuid );
+
+	// Clean the toxic asset list, remove old entries
+	void		flushOldToxicAssets( BOOL force_it );
+
+	// Add an item to the toxic asset map
+	void		markAssetToxic( const LLUUID& uuid );
+
 protected:
 	virtual LLSD getPendingDetails(const request_list_t* requests,
 	 				LLAssetType::EType asset_type,
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index b847f4d04cc..41c97818dcc 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -163,7 +163,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
 	mRegionFlags( REGION_FLAGS_DEFAULT ),
 	mSimAccess( SIM_ACCESS_MIN ),
 	mBillableFactor(1.0),
-	mMaxTasks(MAX_TASKS_PER_REGION),
+	mMaxTasks(DEFAULT_MAX_REGION_WIDE_PRIM_COUNT),
 	mCacheLoaded(FALSE),
 	mCacheEntriesCount(0),
 	mCacheID(),
-- 
GitLab