From ce1f95bade2eeec5732d3275bb54fd1612ab03fb Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Wed, 4 Jan 2012 21:06:54 -0700
Subject: trivial: debug code for SH-2828: [crashhunters] Crash in
 LLRefCount::unref(), bad stacks

---
 indra/newview/llviewerwindow.cpp | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 31dfa1923c..29f951da93 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1956,33 +1956,42 @@ void LLViewerWindow::shutdownViews()
 	// clean up warning logger
 	LLError::removeRecorder(RecordToChatConsole::getInstance());
 
+	llinfos << "Warning logger is cleaned." << llendl ;
+
 	delete mDebugText;
 	mDebugText = NULL;
 	
+	llinfos << "DebugText deleted." << llendl ;
+
 	// Cleanup global views
 	if (gMorphView)
 	{
 		gMorphView->setVisible(FALSE);
 	}
+	llinfos << "Global views cleaned." << llendl ;
 
 	// DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open
 	// will crump with LL_ERRS.
 	LLModalDialog::shutdownModals();
-	
+	llinfos << "LLModalDialog shut down." << llendl; 
+
 	// destroy the nav bar, not currently part of gViewerWindow
 	// *TODO: Make LLNavigationBar part of gViewerWindow
 	if (LLNavigationBar::instanceExists())
 	{
 		delete LLNavigationBar::getInstance();
 	}
+	llinfos << "LLNavigationBar destroyed." << llendl ;
 
 	// destroy menus after instantiating navbar above, as it needs
 	// access to gMenuHolder
 	cleanup_menus();
+	llinfos << "menus destroyed." << llendl ;
 
 	// Delete all child views.
 	delete mRootView;
 	mRootView = NULL;
+	llinfos << "RootView deleted." << llendl ;
 
 	// Automatically deleted as children of mRootView.  Fix the globals.
 	gStatusBar = NULL;
-- 
cgit v1.2.3


From 141089327649f9b89be4ac9cc2b50f56eee62a48 Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Thu, 5 Jan 2012 21:26:06 -0700
Subject: fix for SH-2829: [crashhunters] Crash in
 LLWearable::importFile()/LLOverrideBakedTextureUpdate::LLOverrideBakedTextureUpdate()

---
 indra/newview/llagentwearablesfetch.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp
index 1edc96e165..4097ff707c 100644
--- a/indra/newview/llagentwearablesfetch.cpp
+++ b/indra/newview/llagentwearablesfetch.cpp
@@ -111,6 +111,12 @@ void LLInitialWearablesFetch::add(InitialWearableData &data)
 
 void LLInitialWearablesFetch::processContents()
 {
+	if(!gAgentAvatarp) //no need to process wearables if the agent avatar is deleted.
+	{
+		delete this;
+		return ;
+	}
+
 	// Fetch the wearable items from the Current Outfit Folder
 	LLInventoryModel::cat_array_t cat_array;
 	LLInventoryModel::item_array_t wearable_array;
-- 
cgit v1.2.3


From 837e38d8195b2928648c9c383bea1b3f1cf68fa5 Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Thu, 5 Jan 2012 21:26:35 -0700
Subject: trivial: debug code for SH-2827: [crashhunters] Crash in
 LLPipeline::generateWaterReflection()

---
 indra/llrender/llrender.cpp | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'indra')

diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index cd827f5091..03a9884c2b 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -1434,6 +1434,8 @@ void LLRender::loadIdentity()
 	flush();
 
 	{
+		llassert_always(mMatrixMode < NUM_MATRIX_MODES) ;
+
 		mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].make_identity();
 		mMatHash[mMatrixMode]++;
 	}
-- 
cgit v1.2.3


From f082de03ff24ae8cc6a2de103bc643c392135742 Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Thu, 12 Jan 2012 16:36:56 -0700
Subject: fix for SH-2845, SH-2846, SH-2847, SH-2851: curl crashes and
 out-of-memory crashes.

---
 indra/llmessage/llcurl.cpp                         | 293 +++++++++++++++++----
 indra/llmessage/llcurl.h                           |  22 +-
 indra/llmessage/llhttpassetstorage.cpp             |  10 +-
 indra/llmessage/llhttpclient.cpp                   |  12 +-
 indra/llmessage/lliopipe.cpp                       |   6 +
 indra/llmessage/lliopipe.h                         |   2 +
 indra/llmessage/llpumpio.cpp                       |  50 +++-
 indra/llmessage/llpumpio.h                         |  12 +-
 indra/llmessage/llsdrpcclient.h                    |   3 +
 indra/llmessage/llurlrequest.cpp                   |  18 ++
 indra/llmessage/llurlrequest.h                     |   2 +
 indra/newview/llmeshrepository.cpp                 | 131 +++++----
 indra/newview/llmeshrepository.h                   |   4 +-
 indra/newview/llxmlrpctransaction.cpp              |  19 ++
 .../updater/llupdatedownloader.cpp                 |  23 +-
 15 files changed, 475 insertions(+), 132 deletions(-)

(limited to 'indra')

diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index e17380fdf5..eab2874596 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -72,10 +72,12 @@
 
 static const U32 EASY_HANDLE_POOL_SIZE		= 5;
 static const S32 MULTI_PERFORM_CALL_REPEAT	= 5;
-static const S32 CURL_REQUEST_TIMEOUT = 30; // seconds
+static const S32 CURL_REQUEST_TIMEOUT = 30; // seconds per operation
 static const S32 MAX_ACTIVE_REQUEST_COUNT = 100;
 
-static 
+static const F32 DEFAULT_MULTI_IDLE_TIME = 120.0f ; //seconds
+static const S32 MAX_NUM_OF_HANDLES = 256 ; //max number of handles, (multi handles and easy handles combined).
+
 // DEBUG //
 S32 gCurlEasyCount = 0;
 S32 gCurlMultiCount = 0;
@@ -87,6 +89,8 @@ std::vector<LLMutex*> LLCurl::sSSLMutex;
 std::string LLCurl::sCAPath;
 std::string LLCurl::sCAFile;
 LLCurlThread* LLCurl::sCurlThread = NULL ;
+LLMutex* LLCurl::sHandleMutexp = NULL ;
+S32      LLCurl::sTotalHandles = 0 ;
 
 void check_curl_code(CURLcode code)
 {
@@ -230,7 +234,7 @@ CURL* LLCurl::Easy::allocEasyHandle()
 
 	if (sFreeHandles.empty())
 	{
-		ret = curl_easy_init();
+		ret = LLCurl::newEasyHandle();
 	}
 	else
 	{
@@ -250,16 +254,27 @@ CURL* LLCurl::Easy::allocEasyHandle()
 //static
 void LLCurl::Easy::releaseEasyHandle(CURL* handle)
 {
+	static const S32 MAX_NUM_FREE_HANDLES = 32 ;
+
 	if (!handle)
 	{
-		llerrs << "handle cannot be NULL!" << llendl;
+		return ; //handle allocation failed.
+		//llerrs << "handle cannot be NULL!" << llendl;
 	}
 
 	LLMutexLock lock(sHandleMutexp) ;
 	if (sActiveHandles.find(handle) != sActiveHandles.end())
 	{
 		sActiveHandles.erase(handle);
-		sFreeHandles.insert(handle);
+
+		if(sFreeHandles.size() < MAX_NUM_FREE_HANDLES)
+		{
+			sFreeHandles.insert(handle);
+		}
+		else
+		{
+			LLCurl::deleteEasyHandle(handle) ;
+		}
 	}
 	else
 	{
@@ -517,8 +532,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
 }
 
 ////////////////////////////////////////////////////////////////////////////
-LLMutex* LLCurl::Multi::sMultiInitMutexp = NULL ;
-LLCurl::Multi::Multi()
+LLCurl::Multi::Multi(F32 idle_time_out)
 	: mQueued(0),
 	  mErrorCount(0),
 	  mState(STATE_READY),
@@ -527,28 +541,47 @@ LLCurl::Multi::Multi()
 	  mDeletionMutexp(NULL),
 	  mEasyMutexp(NULL)
 {
-	mCurlMultiHandle = initMulti();
+	mCurlMultiHandle = LLCurl::newMultiHandle();
 	if (!mCurlMultiHandle)
 	{
 		llwarns << "curl_multi_init() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl;
-		mCurlMultiHandle = initMulti();
+		mCurlMultiHandle = LLCurl::newMultiHandle();
 	}
 	
-	llassert_always(mCurlMultiHandle);	
-
-	if(LLCurl::getCurlThread()->getThreaded())
+	//llassert_always(mCurlMultiHandle);	
+	
+	if(mCurlMultiHandle)
 	{
-		mMutexp = new LLMutex(NULL) ;
-		mDeletionMutexp = new LLMutex(NULL) ;
-		mEasyMutexp = new LLMutex(NULL) ;
-	}
-	LLCurl::getCurlThread()->addMulti(this) ;
+		if(LLCurl::getCurlThread()->getThreaded())
+		{
+			mMutexp = new LLMutex(NULL) ;
+			mDeletionMutexp = new LLMutex(NULL) ;
+			mEasyMutexp = new LLMutex(NULL) ;
+		}
+		LLCurl::getCurlThread()->addMulti(this) ;
+
+		mIdleTimeOut = idle_time_out ;
+		if(mIdleTimeOut < DEFAULT_MULTI_IDLE_TIME)
+		{
+			mIdleTimeOut = DEFAULT_MULTI_IDLE_TIME ;
+		}
 
-	++gCurlMultiCount;
+		++gCurlMultiCount;
+	}
 }
 
 LLCurl::Multi::~Multi()
 {
+	cleanup() ;	
+}
+
+void LLCurl::Multi::cleanup()
+{
+	if(!mCurlMultiHandle)
+	{
+		return ; //nothing to clean.
+	}
+
 	// Clean up active
 	for(easy_active_list_t::iterator iter = mEasyActiveList.begin();
 		iter != mEasyActiveList.end(); ++iter)
@@ -564,7 +597,8 @@ LLCurl::Multi::~Multi()
 	for_each(mEasyFreeList.begin(), mEasyFreeList.end(), DeletePointer());	
 	mEasyFreeList.clear();
 
-	check_curl_multi_code(curl_multi_cleanup(mCurlMultiHandle));
+	check_curl_multi_code(LLCurl::deleteMultiHandle(mCurlMultiHandle));
+	mCurlMultiHandle = NULL ;
 
 	delete mMutexp ;
 	mMutexp = NULL ;
@@ -572,15 +606,13 @@ LLCurl::Multi::~Multi()
 	mDeletionMutexp = NULL ;
 	delete mEasyMutexp ;
 	mEasyMutexp = NULL ;
-
+	
+	mQueued = 0 ;
+	mState = STATE_COMPLETED;
+	
 	--gCurlMultiCount;
-}
-
-CURLM* LLCurl::Multi::initMulti()
-{
-	LLMutexLock lock(sMultiInitMutexp) ;
 
-	return curl_multi_init() ;
+	return ;
 }
 
 void LLCurl::Multi::lock()
@@ -604,6 +636,7 @@ void LLCurl::Multi::markDead()
 	LLMutexLock lock(mDeletionMutexp) ;
 	
 	mDead = TRUE ;
+	LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ; 
 }
 
 void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state)
@@ -630,6 +663,11 @@ bool LLCurl::Multi::isCompleted()
 
 bool LLCurl::Multi::waitToComplete()
 {
+	if(!isValid())
+	{
+		return true ;
+	}
+
 	if(!mMutexp) //not threaded
 	{
 		doPerform() ;
@@ -639,7 +677,7 @@ bool LLCurl::Multi::waitToComplete()
 	bool completed = (STATE_COMPLETED == mState) ;
 	if(!completed)
 	{
-		LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ;
+		LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_HIGH) ;
 	}
 	
 	return completed;
@@ -689,7 +727,12 @@ bool LLCurl::Multi::doPerform()
 		}
 
 		mQueued = q;	
-		setState(STATE_COMPLETED) ;
+		setState(STATE_COMPLETED) ;		
+		mIdleTimer.reset() ;
+	}
+	else if(mIdleTimer.getElapsedTimeF32() > mIdleTimeOut) //idle for too long, remove it.
+	{
+		dead = true ;
 	}
 
 	return dead ;
@@ -697,6 +740,11 @@ bool LLCurl::Multi::doPerform()
 
 S32 LLCurl::Multi::process()
 {
+	if(!isValid())
+	{
+		return 0 ;
+	}
+
 	waitToComplete() ;
 
 	if (getState() != STATE_COMPLETED)
@@ -849,7 +897,11 @@ bool LLCurlThread::CurlRequest::processRequest()
 	if(mMulti)
 	{
 		completed = mCurlThread->doMultiPerform(mMulti) ;
-		setPriority(LLQueuedThread::PRIORITY_LOW) ;
+
+		if(!completed)
+		{
+			setPriority(LLQueuedThread::PRIORITY_LOW) ;
+		}
 	}
 
 	return completed ;
@@ -857,24 +909,26 @@ bool LLCurlThread::CurlRequest::processRequest()
 
 void LLCurlThread::CurlRequest::finishRequest(bool completed)
 {
-	mCurlThread->deleteMulti(mMulti) ;
+	if(mMulti->isDead())
+	{
+		mCurlThread->deleteMulti(mMulti) ;
+	}
+	else
+	{
+		mMulti->cleanup() ; //being idle too long, remove the request.
+	}
+
 	mMulti = NULL ;
 }
 	
 LLCurlThread::LLCurlThread(bool threaded) :
 	LLQueuedThread("curlthread", threaded)
 {
-	if(!LLCurl::Multi::sMultiInitMutexp)
-	{
-		LLCurl::Multi::sMultiInitMutexp = new LLMutex(NULL) ;
-	}
 }
 	
 //virtual 
 LLCurlThread::~LLCurlThread() 
 {
-	delete LLCurl::Multi::sMultiInitMutexp ;
-	LLCurl::Multi::sMultiInitMutexp = NULL ;
 }
 
 S32 LLCurlThread::update(F32 max_time_ms)
@@ -896,7 +950,19 @@ void LLCurlThread::addMulti(LLCurl::Multi* multi)
 	
 void LLCurlThread::killMulti(LLCurl::Multi* multi)
 {
-	multi->markDead() ;
+	if(!multi)
+	{
+		return ;
+	}
+
+	if(multi->isValid())
+	{
+		multi->markDead() ;
+	}
+	else
+	{
+		deleteMulti(multi) ;
+	}
 }
 
 //private
@@ -942,7 +1008,14 @@ LLCurlRequest::~LLCurlRequest()
 void LLCurlRequest::addMulti()
 {
 	LLCurl::Multi* multi = new LLCurl::Multi();
-	
+	if(!multi->isValid())
+	{
+		LLCurl::getCurlThread()->killMulti(multi) ;
+		mActiveMulti = NULL ;
+		mActiveRequestCount = 0 ;
+		return;
+	}
+
 	mMultiSet.insert(multi);
 	mActiveMulti = multi;
 	mActiveRequestCount = 0;
@@ -1066,6 +1139,19 @@ S32 LLCurlRequest::process()
 	{
 		curlmulti_set_t::iterator curiter = iter++;
 		LLCurl::Multi* multi = *curiter;
+
+		if(!multi->isValid())
+		{
+			if(multi == mActiveMulti)
+			{				
+				mActiveMulti = NULL ;
+				mActiveRequestCount = 0 ;
+			}
+			mMultiSet.erase(curiter) ;
+			LLCurl::getCurlThread()->killMulti(multi) ;
+			continue ;
+		}
+
 		S32 tres = multi->process();
 		res += tres;
 		if (multi != mActiveMulti && tres == 0 && multi->mQueued == 0)
@@ -1086,6 +1172,19 @@ S32 LLCurlRequest::getQueued()
 	{
 		curlmulti_set_t::iterator curiter = iter++;
 		LLCurl::Multi* multi = *curiter;
+		
+		if(!multi->isValid())
+		{
+			if(multi == mActiveMulti)
+			{				
+				mActiveMulti = NULL ;
+				mActiveRequestCount = 0 ;
+			}
+			LLCurl::getCurlThread()->killMulti(multi);
+			mMultiSet.erase(curiter) ;
+			continue ;
+		}
+
 		queued += multi->mQueued;
 		if (multi->getState() != LLCurl::Multi::STATE_READY)
 		{
@@ -1105,13 +1204,22 @@ LLCurlEasyRequest::LLCurlEasyRequest()
 {
 	mMulti = new LLCurl::Multi();
 	
-	mEasy = mMulti->allocEasy();
-	if (mEasy)
+	if(mMulti->isValid())
 	{
-		mEasy->setErrorBuffer();
-		mEasy->setCA();
-		// Set proxy settings if configured to do so.
-		LLProxy::getInstance()->applyProxySettings(mEasy);
+		mEasy = mMulti->allocEasy();
+		if (mEasy)
+		{
+			mEasy->setErrorBuffer();
+			mEasy->setCA();
+			// Set proxy settings if configured to do so.
+			LLProxy::getInstance()->applyProxySettings(mEasy);
+		}
+	}
+	else
+	{
+		LLCurl::getCurlThread()->killMulti(mMulti) ;
+		mEasy = NULL ;
+		mMulti = NULL ;
 	}
 }
 
@@ -1122,7 +1230,7 @@ LLCurlEasyRequest::~LLCurlEasyRequest()
 	
 void LLCurlEasyRequest::setopt(CURLoption option, S32 value)
 {
-	if (mEasy)
+	if (isValid() && mEasy)
 	{
 		mEasy->setopt(option, value);
 	}
@@ -1130,7 +1238,7 @@ void LLCurlEasyRequest::setopt(CURLoption option, S32 value)
 
 void LLCurlEasyRequest::setoptString(CURLoption option, const std::string& value)
 {
-	if (mEasy)
+	if (isValid() && mEasy)
 	{
 		mEasy->setoptString(option, value);
 	}
@@ -1138,7 +1246,7 @@ void LLCurlEasyRequest::setoptString(CURLoption option, const std::string& value
 
 void LLCurlEasyRequest::setPost(char* postdata, S32 size)
 {
-	if (mEasy)
+	if (isValid() && mEasy)
 	{
 		mEasy->setopt(CURLOPT_POST, 1);
 		mEasy->setopt(CURLOPT_POSTFIELDS, postdata);
@@ -1148,7 +1256,7 @@ void LLCurlEasyRequest::setPost(char* postdata, S32 size)
 
 void LLCurlEasyRequest::setHeaderCallback(curl_header_callback callback, void* userdata)
 {
-	if (mEasy)
+	if (isValid() && mEasy)
 	{
 		mEasy->setopt(CURLOPT_HEADERFUNCTION, (void*)callback);
 		mEasy->setopt(CURLOPT_HEADERDATA, userdata); // aka CURLOPT_WRITEHEADER
@@ -1157,7 +1265,7 @@ void LLCurlEasyRequest::setHeaderCallback(curl_header_callback callback, void* u
 
 void LLCurlEasyRequest::setWriteCallback(curl_write_callback callback, void* userdata)
 {
-	if (mEasy)
+	if (isValid() && mEasy)
 	{
 		mEasy->setopt(CURLOPT_WRITEFUNCTION, (void*)callback);
 		mEasy->setopt(CURLOPT_WRITEDATA, userdata);
@@ -1166,7 +1274,7 @@ void LLCurlEasyRequest::setWriteCallback(curl_write_callback callback, void* use
 
 void LLCurlEasyRequest::setReadCallback(curl_read_callback callback, void* userdata)
 {
-	if (mEasy)
+	if (isValid() && mEasy)
 	{
 		mEasy->setopt(CURLOPT_READFUNCTION, (void*)callback);
 		mEasy->setopt(CURLOPT_READDATA, userdata);
@@ -1175,7 +1283,7 @@ void LLCurlEasyRequest::setReadCallback(curl_read_callback callback, void* userd
 
 void LLCurlEasyRequest::setSSLCtxCallback(curl_ssl_ctx_callback callback, void* userdata)
 {
-	if (mEasy)
+	if (isValid() && mEasy)
 	{
 		mEasy->setopt(CURLOPT_SSL_CTX_FUNCTION, (void*)callback);
 		mEasy->setopt(CURLOPT_SSL_CTX_DATA, userdata);
@@ -1184,7 +1292,7 @@ void LLCurlEasyRequest::setSSLCtxCallback(curl_ssl_ctx_callback callback, void*
 
 void LLCurlEasyRequest::slist_append(const char* str)
 {
-	if (mEasy)
+	if (isValid() && mEasy)
 	{
 		mEasy->slist_append(str);
 	}
@@ -1195,7 +1303,7 @@ void LLCurlEasyRequest::sendRequest(const std::string& url)
 	llassert_always(!mRequestSent);
 	mRequestSent = true;
 	lldebugs << url << llendl;
-	if (mEasy)
+	if (isValid() && mEasy)
 	{
 		mEasy->setHeaders();
 		mEasy->setoptString(CURLOPT_URL, url);
@@ -1207,7 +1315,7 @@ void LLCurlEasyRequest::requestComplete()
 {
 	llassert_always(mRequestSent);
 	mRequestSent = false;
-	if (mEasy)
+	if (isValid() && mEasy)
 	{
 		mMulti->removeEasy(mEasy);
 	}
@@ -1216,6 +1324,10 @@ void LLCurlEasyRequest::requestComplete()
 // Usage: Call getRestult until it returns false (no more messages)
 bool LLCurlEasyRequest::getResult(CURLcode* result, LLCurl::TransferInfo* info)
 {
+	if(!isValid())
+	{
+		return false ;
+	}
 	if (!mMulti->isCompleted())
 	{ //we're busy, try again later
 		return false;
@@ -1280,7 +1392,7 @@ CURLMsg* LLCurlEasyRequest::info_read(S32* q, LLCurl::TransferInfo* info)
 
 std::string LLCurlEasyRequest::getErrorString()
 {
-	return mEasy ? std::string(mEasy->getErrorBuffer()) : std::string();
+	return isValid() &&  mEasy ? std::string(mEasy->getErrorBuffer()) : std::string();
 }
 
 ////////////////////////////////////////////////////////////////////////////
@@ -1328,6 +1440,7 @@ void LLCurl::initClass(bool multi_threaded)
 	sCurlThread = new LLCurlThread(multi_threaded) ;
 	if(multi_threaded)
 	{
+		sHandleMutexp = new LLMutex(NULL) ;
 		Easy::sHandleMutexp = new LLMutex(NULL) ;
 	}
 }
@@ -1354,7 +1467,7 @@ void LLCurl::cleanupClass()
 	for (std::set<CURL*>::iterator iter = Easy::sFreeHandles.begin(); iter != Easy::sFreeHandles.end(); ++iter)
 	{
 		CURL* curl = *iter;
-		curl_easy_cleanup(curl);
+		LLCurl::deleteEasyHandle(curl);
 	}
 
 	Easy::sFreeHandles.clear();
@@ -1362,9 +1475,77 @@ void LLCurl::cleanupClass()
 	delete Easy::sHandleMutexp ;
 	Easy::sHandleMutexp = NULL ;
 
+	delete sHandleMutexp ;
+	sHandleMutexp = NULL ;
+
 	llassert(Easy::sActiveHandles.empty());
 }
 
+//static 
+CURLM* LLCurl::newMultiHandle()
+{
+	LLMutexLock lock(sHandleMutexp) ;
+
+	if(sTotalHandles + 1 > MAX_NUM_OF_HANDLES)
+	{
+		llwarns << "no more handles available." << llendl ;
+		return NULL ; //failed
+	}
+	sTotalHandles++;
+
+	CURLM* ret = curl_multi_init() ;
+	if(!ret)
+	{
+		llwarns << "curl_multi_init failed." << llendl ;
+	}
+
+	return ret ;
+}
+
+//static 
+CURLMcode  LLCurl::deleteMultiHandle(CURLM* handle)
+{
+	if(handle)
+	{
+		LLMutexLock lock(sHandleMutexp) ;		
+		sTotalHandles-- ;
+		return curl_multi_cleanup(handle) ;
+	}
+	return CURLM_OK ;
+}
+
+//static 
+CURL*  LLCurl::newEasyHandle()
+{
+	LLMutexLock lock(sHandleMutexp) ;
+
+	if(sTotalHandles + 1 > MAX_NUM_OF_HANDLES)
+	{
+		llwarns << "no more handles available." << llendl ;
+		return NULL ; //failed
+	}
+	sTotalHandles++;
+
+	CURL* ret = curl_easy_init() ;
+	if(!ret)
+	{
+		llwarns << "curl_easy_init failed." << llendl ;
+	}
+
+	return ret ;
+}
+
+//static 
+void  LLCurl::deleteEasyHandle(CURL* handle)
+{
+	if(handle)
+	{
+		LLMutexLock lock(sHandleMutexp) ;
+		curl_easy_cleanup(handle) ;
+		sTotalHandles-- ;
+	}
+}
+
 const unsigned int LLCurl::MAX_REDIRECTS = 5;
 
 // Provide access to LLCurl free functions outside of llcurl.cpp without polluting the global namespace.
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index 9c2c215c7a..32da911cbf 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -43,6 +43,7 @@
 #include "llsd.h"
 #include "llthread.h"
 #include "llqueuedthread.h"
+#include "llframetimer.h"
 
 class LLMutex;
 class LLCurlThread;
@@ -182,11 +183,20 @@ public:
 	static unsigned long ssl_thread_id(void);
 
 	static LLCurlThread* getCurlThread() { return sCurlThread ;}
+
+	static CURLM* newMultiHandle() ;
+	static CURLMcode deleteMultiHandle(CURLM* handle) ;
+	static CURL*  newEasyHandle() ;
+	static void   deleteEasyHandle(CURL* handle) ;
+
 private:
 	static std::string sCAPath;
 	static std::string sCAFile;
 	static const unsigned int MAX_REDIRECTS;
 	static LLCurlThread* sCurlThread;
+
+	static LLMutex* sHandleMutexp ;
+	static S32      sTotalHandles ;
 };
 
 class LLCurl::Easy
@@ -277,7 +287,7 @@ public:
 		STATE_COMPLETED=2
 	} ePerformState;
 
-	Multi();	
+	Multi(F32 idle_time_out = 0.f);	
 
 	LLCurl::Easy* allocEasy();
 	bool addEasy(LLCurl::Easy* easy);	
@@ -288,7 +298,10 @@ public:
 
 	void setState(ePerformState state) ;
 	ePerformState getState() ;
+	
 	bool isCompleted() ;
+	bool isValid() {return mCurlMultiHandle != NULL ;}
+	bool isDead() {return mDead;}
 
 	bool waitToComplete() ;
 
@@ -299,9 +312,9 @@ public:
 	S32 mQueued;
 	S32 mErrorCount;
 	
-	static CURLM* initMulti() ;
 private:
 	void easyFree(LLCurl::Easy*);
+	void cleanup() ;
 	
 	CURLM* mCurlMultiHandle;
 
@@ -319,8 +332,8 @@ private:
 	LLMutex* mMutexp ;
 	LLMutex* mDeletionMutexp ;
 	LLMutex* mEasyMutexp ;
-
-	static LLMutex* sMultiInitMutexp ;
+	LLFrameTimer mIdleTimer ;
+	F32 mIdleTimeOut;
 };
 
 class LLCurlThread : public LLQueuedThread
@@ -414,6 +427,7 @@ public:
 	std::string getErrorString();
 	bool isCompleted() {return mMulti->isCompleted() ;}
 	bool wait() { return mMulti->waitToComplete(); }
+	bool isValid() {return mMulti && mMulti->isValid(); }
 
 	LLCurl::Easy* getEasy() const { return mEasy; }
 
diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp
index 2bca517e97..612d765969 100644
--- a/indra/llmessage/llhttpassetstorage.cpp
+++ b/indra/llmessage/llhttpassetstorage.cpp
@@ -232,7 +232,8 @@ LLSD LLHTTPAssetRequest::getFullDetails() const
 void LLHTTPAssetRequest::setupCurlHandle()
 {
 	// *NOTE: Similar code exists in mapserver/llcurlutil.cpp  JC
-	mCurlHandle = curl_easy_init();
+	mCurlHandle = LLCurl::newEasyHandle();
+	llassert_always(mCurlHandle != NULL) ;
 
 	// Apply proxy settings if configured to do so
 	LLProxy::getInstance()->applyProxySettings(mCurlHandle);
@@ -278,7 +279,7 @@ void LLHTTPAssetRequest::setupCurlHandle()
 
 void LLHTTPAssetRequest::cleanupCurlHandle()
 {
-	curl_easy_cleanup(mCurlHandle);
+	LLCurl::deleteEasyHandle(mCurlHandle);
 	if (mAssetStoragep)
 	{
 		// Terminating a request.  Thus upload or download is no longer pending.
@@ -429,12 +430,13 @@ void LLHTTPAssetStorage::_init(const std::string& web_host, const std::string& l
 
 	// curl_global_init moved to LLCurl::initClass()
 	
-	mCurlMultiHandle = curl_multi_init();
+	mCurlMultiHandle = LLCurl::newMultiHandle() ;
+	llassert_always(mCurlMultiHandle != NULL) ;
 }
 
 LLHTTPAssetStorage::~LLHTTPAssetStorage()
 {
-	curl_multi_cleanup(mCurlMultiHandle);
+	LLCurl::deleteMultiHandle(mCurlMultiHandle);
 	mCurlMultiHandle = NULL;
 	
 	// curl_global_cleanup moved to LLCurl::initClass()
diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp
index dd4e3a6300..231cb7ca8f 100644
--- a/indra/llmessage/llhttpclient.cpp
+++ b/indra/llmessage/llhttpclient.cpp
@@ -228,6 +228,12 @@ static void request(
 	LLPumpIO::chain_t chain;
 
 	LLURLRequest* req = new LLURLRequest(method, url);
+	if(!req->isValid())//failed
+	{
+		delete req ;
+		return ;
+	}
+
 	req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req);
 
 	
@@ -423,7 +429,9 @@ static LLSD blocking_request(
 {
 	lldebugs << "blockingRequest of " << url << llendl;
 	char curl_error_buffer[CURL_ERROR_SIZE] = "\0";
-	CURL* curlp = curl_easy_init();
+	CURL* curlp = LLCurl::newEasyHandle();
+	llassert_always(curlp != NULL) ;
+
 	LLHTTPBuffer http_buffer;
 	std::string body_str;
 	
@@ -517,7 +525,7 @@ static LLSD blocking_request(
 	}
 
 	// * Cleanup
-	curl_easy_cleanup(curlp);
+	LLCurl::deleteEasyHandle(curlp);
 	return response;
 }
 
diff --git a/indra/llmessage/lliopipe.cpp b/indra/llmessage/lliopipe.cpp
index 6e4eec74a6..8f827f7a30 100644
--- a/indra/llmessage/lliopipe.cpp
+++ b/indra/llmessage/lliopipe.cpp
@@ -75,6 +75,12 @@ LLIOPipe::~LLIOPipe()
 	//lldebugs << "destroying LLIOPipe" << llendl;
 }
 
+//virtual 
+bool LLIOPipe::isValid() 
+{
+	return true ;
+}
+
 // static
 std::string LLIOPipe::lookupStatusString(EStatus status)
 {
diff --git a/indra/llmessage/lliopipe.h b/indra/llmessage/lliopipe.h
index 8e656b6da1..cbd17b5a3d 100644
--- a/indra/llmessage/lliopipe.h
+++ b/indra/llmessage/lliopipe.h
@@ -231,6 +231,8 @@ public:
 	 */
 	virtual ~LLIOPipe();
 
+	virtual bool isValid() ;
+
 protected:
 	/**
 	 * @brief Base Constructor.
diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp
index a8d2a0a224..0ff300efd0 100644
--- a/indra/llmessage/llpumpio.cpp
+++ b/indra/llmessage/llpumpio.cpp
@@ -195,7 +195,7 @@ bool LLPumpIO::prime(apr_pool_t* pool)
 	return ((pool == NULL) ? false : true);
 }
 
-bool LLPumpIO::addChain(const chain_t& chain, F32 timeout)
+bool LLPumpIO::addChain(const chain_t& chain, F32 timeout, bool has_curl_request)
 {
 	LLMemType m1(LLMemType::MTYPE_IO_PUMP);
 	if(chain.empty()) return false;
@@ -204,6 +204,7 @@ bool LLPumpIO::addChain(const chain_t& chain, F32 timeout)
 	LLScopedLock lock(mChainsMutex);
 #endif
 	LLChainInfo info;
+	info.mHasCurlRequest = has_curl_request;
 	info.setTimeoutSeconds(timeout);
 	info.mData = LLIOPipe::buffer_ptr_t(new LLBufferArray);
 	LLLinkInfo link;
@@ -440,6 +441,15 @@ void LLPumpIO::pump()
 
 static LLFastTimer::DeclareTimer FTM_PUMP_IO("Pump IO");
 
+LLPumpIO::current_chain_t LLPumpIO::removeRunningChain(LLPumpIO::current_chain_t& run_chain) 
+{
+	std::for_each(
+				(*run_chain).mDescriptors.begin(),
+				(*run_chain).mDescriptors.end(),
+				ll_delete_apr_pollset_fd_client_data());
+	return mRunningChains.erase(run_chain);
+}
+
 //timeout is in microseconds
 void LLPumpIO::pump(const S32& poll_timeout)
 {
@@ -585,10 +595,16 @@ void LLPumpIO::pump(const S32& poll_timeout)
 //						<< (*run_chain).mChainLinks[0].mPipe
 //						<< " because we reached the end." << llendl;
 #endif
-				run_chain = mRunningChains.erase(run_chain);
+				run_chain = removeRunningChain(run_chain);
 				continue;
 			}
 		}
+		else if(isChainExpired(*run_chain))
+		{
+			run_chain = removeRunningChain(run_chain);
+			continue;
+		}
+
 		PUMP_DEBUG;
 		if((*run_chain).mLock)
 		{
@@ -696,11 +712,7 @@ void LLPumpIO::pump(const S32& poll_timeout)
 			PUMP_DEBUG;
 			// This chain is done. Clean up any allocated memory and
 			// erase the chain info.
-			std::for_each(
-				(*run_chain).mDescriptors.begin(),
-				(*run_chain).mDescriptors.end(),
-				ll_delete_apr_pollset_fd_client_data());
-			run_chain = mRunningChains.erase(run_chain);
+			run_chain = removeRunningChain(run_chain);
 
 			// *NOTE: may not always need to rebuild the pollset.
 			mRebuildPollset = true;
@@ -1095,6 +1107,24 @@ void LLPumpIO::processChain(LLChainInfo& chain)
 	PUMP_DEBUG;
 }
 
+bool LLPumpIO::isChainExpired(LLChainInfo& chain)
+{
+	if(!chain.mHasCurlRequest)
+	{
+		return false ;
+	}
+
+	for(links_t::iterator iter = chain.mChainLinks.begin(); iter != chain.mChainLinks.end(); ++iter)
+	{
+		if(!(*iter).mPipe->isValid())
+		{
+			return true ;
+		}
+	}
+
+	return false ;
+}
+
 bool LLPumpIO::handleChainError(
 	LLChainInfo& chain,
 	LLIOPipe::EStatus error)
@@ -1136,6 +1166,9 @@ bool LLPumpIO::handleChainError(
 #endif
 			keep_going = false;
 			break;
+		case LLIOPipe::STATUS_EXPIRED:
+			keep_going = false;
+			break ;
 		default:
 			if(LLIOPipe::isSuccess(error))
 			{
@@ -1157,7 +1190,8 @@ bool LLPumpIO::handleChainError(
 LLPumpIO::LLChainInfo::LLChainInfo() :
 	mInit(false),
 	mLock(0),
-	mEOS(false)
+	mEOS(false),
+	mHasCurlRequest(false)
 {
 	LLMemType m1(LLMemType::MTYPE_IO_PUMP);
 	mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS);
diff --git a/indra/llmessage/llpumpio.h b/indra/llmessage/llpumpio.h
index 9303c9d7fc..e405124403 100644
--- a/indra/llmessage/llpumpio.h
+++ b/indra/llmessage/llpumpio.h
@@ -113,7 +113,7 @@ public:
 	 * expire. Pass in 0.0f to never expire.
 	 * @return Returns true if anything was added to the pump.
 	 */
-	bool addChain(const chain_t& chain, F32 timeout);
+	bool addChain(const chain_t& chain, F32 timeout, bool has_curl_request = false);
 	
 	/** 
 	 * @brief Struct to associate a pipe with it's buffer io indexes.
@@ -356,12 +356,13 @@ protected:
 
 		// basic member data
 		bool mInit;
+		bool mEOS;
+		bool mHasCurlRequest;
 		S32 mLock;
 		LLFrameTimer mTimer;
 		links_t::iterator mHead;
 		links_t mChainLinks;
-		LLIOPipe::buffer_ptr_t mData;
-		bool mEOS;
+		LLIOPipe::buffer_ptr_t mData;		
 		LLSD mContext;
 
 		// tracking inside the pump
@@ -402,7 +403,7 @@ protected:
 protected:
 	void initialize(apr_pool_t* pool);
 	void cleanup();
-
+	current_chain_t removeRunningChain(current_chain_t& chain) ;
 	/** 
 	 * @brief Given the internal state of the chains, rebuild the pollset
 	 * @see setConditional()
@@ -429,6 +430,9 @@ protected:
 	 */
 	bool handleChainError(LLChainInfo& chain, LLIOPipe::EStatus error);
 
+	//if the chain is expired, remove it
+	bool isChainExpired(LLChainInfo& chain) ;
+
 public:
 	/** 
 	 * @brief Return number of running chains.
diff --git a/indra/llmessage/llsdrpcclient.h b/indra/llmessage/llsdrpcclient.h
index 9fb49a5c33..235077179e 100644
--- a/indra/llmessage/llsdrpcclient.h
+++ b/indra/llmessage/llsdrpcclient.h
@@ -239,6 +239,8 @@ public:
 	LLSDRPCClientFactory(const std::string& fixed_url) : mURL(fixed_url) {}
 	virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
 	{
+		llerrs << "Can not call this." << llendl ;
+
 		lldebugs << "LLSDRPCClientFactory::build" << llendl;
 		LLIOPipe::ptr_t service(new Client);
 		chain.push_back(service);
@@ -282,6 +284,7 @@ public:
 	LLXMLSDRPCClientFactory(const std::string& fixed_url) : mURL(fixed_url) {}
 	virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
 	{
+		llerrs << "who calls this?" << llendl ;
 		lldebugs << "LLXMLSDRPCClientFactory::build" << llendl;
 		LLIOPipe::ptr_t service(new Client);
 		chain.push_back(service);
diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index 261e57e79e..f02c636838 100644
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -83,6 +83,12 @@ LLURLRequestDetail::LLURLRequestDetail() :
 {
 	LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
 	mCurlRequest = new LLCurlEasyRequest();
+	
+	if(!mCurlRequest->isValid()) //failed.
+	{
+		delete mCurlRequest ;
+		mCurlRequest = NULL ;
+	}
 }
 
 LLURLRequestDetail::~LLURLRequestDetail()
@@ -250,12 +256,24 @@ void LLURLRequest::allowCookies()
 	mDetail->mCurlRequest->setoptString(CURLOPT_COOKIEFILE, "");
 }
 
+//virtual 
+bool LLURLRequest::isValid() 
+{
+	return mDetail->mCurlRequest && mDetail->mCurlRequest->isValid(); 
+}
+
 // virtual
 LLIOPipe::EStatus LLURLRequest::handleError(
 	LLIOPipe::EStatus status,
 	LLPumpIO* pump)
 {
 	LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
+	
+	if(!isValid())
+	{
+		return STATUS_EXPIRED ;
+	}
+
 	if(mCompletionCallback && pump)
 	{
 		LLURLRequestComplete* complete = NULL;
diff --git a/indra/llmessage/llurlrequest.h b/indra/llmessage/llurlrequest.h
index ec5c2c1941..44d358d906 100644
--- a/indra/llmessage/llurlrequest.h
+++ b/indra/llmessage/llurlrequest.h
@@ -188,6 +188,8 @@ public:
 	 */
 	void allowCookies();
 
+	/*virtual*/ bool isValid() ;
+
 public:
 	/** 
 	 * @brief Give this pipe a chance to handle a generated error
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index a97e256c89..c64479f589 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -498,9 +498,11 @@ void LLMeshRepoThread::run()
 					LODRequest req = mLODReqQ.front();
 					mLODReqQ.pop();
 					mMutex->unlock();
-					if (fetchMeshLOD(req.mMeshParams, req.mLOD))
+					if (!fetchMeshLOD(req.mMeshParams, req.mLOD, count))//failed, resubmit
 					{
-						count++;
+						mMutex->lock();
+						mLODReqQ.push(req) ; 
+						mMutex->unlock();
 					}
 				}
 			}
@@ -512,9 +514,11 @@ void LLMeshRepoThread::run()
 					HeaderRequest req = mHeaderReqQ.front();
 					mHeaderReqQ.pop();
 					mMutex->unlock();
-					if (fetchMeshHeader(req.mMeshParams))
+					if (!fetchMeshHeader(req.mMeshParams, count))//failed, resubmit
 					{
-						count++;
+						mMutex->lock();
+						mHeaderReqQ.push(req) ;
+						mMutex->unlock();
 					}
 				}
 			}
@@ -658,6 +662,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
 		return false;
 	}
 
+	bool ret = true ;
 	U32 header_size = mMeshHeaderSize[mesh_id];
 	
 	if (header_size > 0)
@@ -673,7 +678,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
 			//check VFS for mesh skin info
 			LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH);
 			if (file.getSize() >= offset+size)
-			{
+			{				
 				LLMeshRepository::sCacheBytesRead += size;
 				file.seek(offset);
 				U8* buffer = new U8[size];
@@ -689,7 +694,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
 				if (!zero)
 				{ //attempt to parse
 					if (skinInfoReceived(mesh_id, buffer, size))
-					{
+					{						
 						delete[] buffer;
 						return true;
 					}
@@ -704,11 +709,14 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
 
 			std::string http_url = constructUrl(mesh_id);
 			if (!http_url.empty())
-			{
-				++sActiveLODRequests;
-				LLMeshRepository::sHTTPRequestCount++;
-				mCurlRequest->getByteRange(constructUrl(mesh_id), headers, offset, size,
+			{				
+				ret = mCurlRequest->getByteRange(http_url, headers, offset, size,
 										   new LLMeshSkinInfoResponder(mesh_id, offset, size));
+				if(ret)
+				{
+					++sActiveLODRequests;
+					LLMeshRepository::sHTTPRequestCount++;
+				}
 			}
 		}
 	}
@@ -718,7 +726,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
 	}
 
 	//early out was not hit, effectively fetched
-	return true;
+	return ret;
 }
 
 bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
@@ -732,7 +740,8 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
 	}
 
 	U32 header_size = mMeshHeaderSize[mesh_id];
-
+	bool ret = true ;
+	
 	if (header_size > 0)
 	{
 		S32 version = mMeshHeader[mesh_id]["version"].asInteger();
@@ -748,6 +757,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
 			if (file.getSize() >= offset+size)
 			{
 				LLMeshRepository::sCacheBytesRead += size;
+
 				file.seek(offset);
 				U8* buffer = new U8[size];
 				file.read(buffer, size);
@@ -777,11 +787,14 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
 
 			std::string http_url = constructUrl(mesh_id);
 			if (!http_url.empty())
-			{
-				++sActiveLODRequests;
-				LLMeshRepository::sHTTPRequestCount++;
-				mCurlRequest->getByteRange(http_url, headers, offset, size,
+			{				
+				ret = mCurlRequest->getByteRange(http_url, headers, offset, size,
 										   new LLMeshDecompositionResponder(mesh_id, offset, size));
+				if(ret)
+				{
+					++sActiveLODRequests;
+					LLMeshRepository::sHTTPRequestCount++;
+				}
 			}
 		}
 	}
@@ -791,7 +804,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
 	}
 
 	//early out was not hit, effectively fetched
-	return true;
+	return ret;
 }
 
 bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
@@ -805,6 +818,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
 	}
 
 	U32 header_size = mMeshHeaderSize[mesh_id];
+	bool ret = true ;
 
 	if (header_size > 0)
 	{
@@ -850,11 +864,15 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
 
 			std::string http_url = constructUrl(mesh_id);
 			if (!http_url.empty())
-			{
-				++sActiveLODRequests;
-				LLMeshRepository::sHTTPRequestCount++;
-				mCurlRequest->getByteRange(http_url, headers, offset, size,
+			{				
+				ret = mCurlRequest->getByteRange(http_url, headers, offset, size,
 										   new LLMeshPhysicsShapeResponder(mesh_id, offset, size));
+
+				if(ret)
+				{
+					++sActiveLODRequests;
+					LLMeshRepository::sHTTPRequestCount++;
+				}
 			}
 		}
 		else
@@ -868,13 +886,12 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
 	}
 
 	//early out was not hit, effectively fetched
-	return true;
+	return ret;
 }
 
-bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
+//return false if failed to get header
+bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count)
 {
-	bool retval = false;
-
 	{
 		//look for mesh in asset in vfs
 		LLVFile file(gVFS, mesh_params.getSculptID(), LLAssetType::AT_MESH);
@@ -889,36 +906,40 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
 			file.read(buffer, bytes);
 			if (headerReceived(mesh_params, buffer, bytes))
 			{ //did not do an HTTP request, return false
-				return false;
+				return true;
 			}
 		}
 	}
 
-	//either cache entry doesn't exist or is corrupt, request header from simulator
-
+	//either cache entry doesn't exist or is corrupt, request header from simulator	
+	bool retval = true ;
 	std::vector<std::string> headers;
 	headers.push_back("Accept: application/octet-stream");
 
 	std::string http_url = constructUrl(mesh_params.getSculptID());
 	if (!http_url.empty())
 	{
-		++sActiveHeaderRequests;
-		retval = true;
 		//grab first 4KB if we're going to bother with a fetch.  Cache will prevent future fetches if a full mesh fits
 		//within the first 4KB
-		//NOTE -- this will break of headers ever exceed 4KB
-		LLMeshRepository::sHTTPRequestCount++;
-		mCurlRequest->getByteRange(http_url, headers, 0, 4096, new LLMeshHeaderResponder(mesh_params));
+		//NOTE -- this will break of headers ever exceed 4KB		
+		retval = mCurlRequest->getByteRange(http_url, headers, 0, 4096, new LLMeshHeaderResponder(mesh_params));
+		if(retval)
+		{
+			++sActiveHeaderRequests;
+			LLMeshRepository::sHTTPRequestCount++;
+		}
+		count++;
 	}
 
 	return retval;
 }
 
-bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
+//return false if failed to get mesh lod.
+bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count)
 { //protected by mMutex
 	mHeaderMutex->lock();
 
-	bool retval = false;
+	bool retval = true;
 
 	LLUUID mesh_id = mesh_params.getSculptID();
 	
@@ -955,7 +976,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
 					if (lodReceived(mesh_params, lod, buffer, size))
 					{
 						delete[] buffer;
-						return false;
+						return true;
 					}
 				}
 
@@ -968,12 +989,16 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
 
 			std::string http_url = constructUrl(mesh_id);
 			if (!http_url.empty())
-			{
-				++sActiveLODRequests;
-				retval = true;
-				LLMeshRepository::sHTTPRequestCount++;
-				mCurlRequest->getByteRange(constructUrl(mesh_id), headers, offset, size,
+			{				
+				retval = mCurlRequest->getByteRange(constructUrl(mesh_id), headers, offset, size,
 										   new LLMeshLODResponder(mesh_params, lod, offset, size));
+
+				if(retval)
+				{
+					++sActiveLODRequests;				
+					LLMeshRepository::sHTTPRequestCount++;
+				}
+				count++;
 			}
 			else
 			{
@@ -1540,8 +1565,17 @@ void LLMeshUploadThread::doWholeModelUpload()
 		LLSD body = full_model_data["asset_resources"];
 		dump_llsd_to_file(body,make_dump_name("whole_model_body_",dump_num));
 		LLCurlRequest::headers_t headers;
-		mCurlRequest->post(mWholeModelUploadURL, headers, body,
-						   new LLWholeModelUploadResponder(this, full_model_data, mUploadObserverHandle), mMeshUploadTimeOut);
+
+		{
+			LLCurl::ResponderPtr responder = new LLWholeModelUploadResponder(this, full_model_data, mUploadObserverHandle) ;
+
+			while(!mCurlRequest->post(mWholeModelUploadURL, headers, body, responder, mMeshUploadTimeOut))
+			{
+				//sleep for 10ms to prevent eating a whole core
+				apr_sleep(10000);
+			}
+		}
+
 		do
 		{
 			mCurlRequest->process();
@@ -1571,8 +1605,15 @@ void LLMeshUploadThread::requestWholeModelFee()
 
 	mPendingUploads++;
 	LLCurlRequest::headers_t headers;
-	mCurlRequest->post(mWholeModelFeeCapability, headers, model_data,
-					   new LLWholeModelFeeResponder(this,model_data, mFeeObserverHandle), mMeshUploadTimeOut);
+
+	{
+		LLCurl::ResponderPtr responder = new LLWholeModelFeeResponder(this,model_data, mFeeObserverHandle) ;
+		while(!mCurlRequest->post(mWholeModelFeeCapability, headers, model_data, responder, mMeshUploadTimeOut))
+		{
+			//sleep for 10ms to prevent eating a whole core
+			apr_sleep(10000);
+		}
+	}
 
 	do
 	{
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 31b84ea0d9..2efe810438 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -323,8 +323,8 @@ public:
 	virtual void run();
 
 	void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
-	bool fetchMeshHeader(const LLVolumeParams& mesh_params);
-	bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
+	bool fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count);
+	bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count);
 	bool headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size);
 	bool lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size);
 	bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 920a9a3752..0da70d398b 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -305,6 +305,15 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
 	{
 		mCurlRequest = new LLCurlEasyRequest();
 	}
+	if(!mCurlRequest->isValid())
+	{
+		llwarns << "mCurlRequest is invalid." << llendl ;
+
+		delete mCurlRequest ;
+		mCurlRequest = NULL ;
+		return ;
+	}
+
 	mErrorCert = NULL;
 
 //	mCurlRequest->setopt(CURLOPT_VERBOSE, 1); // useful for debugging
@@ -357,10 +366,20 @@ LLXMLRPCTransaction::Impl::~Impl()
 	}
 	
 	delete mCurlRequest;
+	mCurlRequest = NULL ;
 }
 
 bool LLXMLRPCTransaction::Impl::process()
 {
+	if(!mCurlRequest || !mCurlRequest->isValid())
+	{
+		llwarns << "transaction failed." << llendl ;
+
+		delete mCurlRequest ;
+		mCurlRequest = NULL ;
+		return true ; //failed, quit.
+	}
+
 	switch(mStatus)
 	{
 		case LLXMLRPCTransaction::StatusComplete:
diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index e88d1bf811..19ac418e9e 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -39,7 +39,7 @@
 #include "llsdserialize.h"
 #include "llthread.h"
 #include "llupdaterservice.h"
-
+#include "llcurl.h"
 
 class LLUpdateDownloader::Implementation:
 	public LLThread
@@ -198,13 +198,19 @@ LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client &
 
 LLUpdateDownloader::Implementation::~Implementation()
 {
-	if(isDownloading()) {
+	if(isDownloading()) 
+	{
 		cancel();
 		shutdown();
-	} else {
+	} 
+	else 
+	{
 		; // No op.
 	}
-	if(mCurl) curl_easy_cleanup(mCurl);
+	if(mCurl)
+	{
+		LLCurl::deleteEasyHandle(mCurl);
+	}
 }
 
 
@@ -406,9 +412,12 @@ void LLUpdateDownloader::Implementation::run(void)
 
 void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & url, bool processHeader)
 {
-	if(mCurl == 0) {
-		mCurl = curl_easy_init();
-	} else {
+	if(mCurl == 0) 
+	{
+		mCurl = LLCurl::newEasyHandle();
+	} 
+	else 
+	{
 		curl_easy_reset(mCurl);
 	}
 	
-- 
cgit v1.2.3


From 11bd5cb86025376a198e45330116de4757b5c89e Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Thu, 12 Jan 2012 20:32:32 -0700
Subject: trivial: fix a mac build error.

---
 indra/llmessage/llcurl.cpp | 9 ++++++++-
 indra/llmessage/llcurl.h   | 1 +
 2 files changed, 9 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index eab2874596..277c274f52 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -915,7 +915,7 @@ void LLCurlThread::CurlRequest::finishRequest(bool completed)
 	}
 	else
 	{
-		mMulti->cleanup() ; //being idle too long, remove the request.
+		mCurlThread->cleanupMulti(mMulti) ; //being idle too long, remove the request.
 	}
 
 	mMulti = NULL ;
@@ -976,6 +976,13 @@ void LLCurlThread::deleteMulti(LLCurl::Multi* multi)
 {
 	delete multi ;
 }
+
+//private
+void LLCurlThread::cleanupMulti(LLCurl::Multi* multi) 
+{
+	multi->cleanup() ;
+}
+
 //------------------------------------------------------------
 
 //static
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index 32da911cbf..2b23ac9763 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -370,6 +370,7 @@ public:
 private:
 	bool doMultiPerform(LLCurl::Multi* multi) ;
 	void deleteMulti(LLCurl::Multi* multi) ;
+	void cleanupMulti(LLCurl::Multi* multi) ;
 } ;
 
 namespace boost
-- 
cgit v1.2.3


From a6c638d882919b58186a6859644d61cdb5e45a7b Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Tue, 17 Jan 2012 17:45:52 -0700
Subject: more exception handlings for llcurl fixes.

---
 indra/llmessage/llpumpio.h      |  1 +
 indra/llmessage/llsdrpcclient.h | 25 ++++++++++++++++++-------
 2 files changed, 19 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/llmessage/llpumpio.h b/indra/llmessage/llpumpio.h
index e405124403..d2c5d37571 100644
--- a/indra/llmessage/llpumpio.h
+++ b/indra/llmessage/llpumpio.h
@@ -111,6 +111,7 @@ public:
 	 * @param chain The pipes for the chain
 	 * @param timeout The number of seconds in the future to
 	 * expire. Pass in 0.0f to never expire.
+	 * @param has_curl_request The chain contains LLURLRequest if true.
 	 * @return Returns true if anything was added to the pump.
 	 */
 	bool addChain(const chain_t& chain, F32 timeout, bool has_curl_request = false);
diff --git a/indra/llmessage/llsdrpcclient.h b/indra/llmessage/llsdrpcclient.h
index 235077179e..0cecf4f688 100644
--- a/indra/llmessage/llsdrpcclient.h
+++ b/indra/llmessage/llsdrpcclient.h
@@ -239,12 +239,17 @@ public:
 	LLSDRPCClientFactory(const std::string& fixed_url) : mURL(fixed_url) {}
 	virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
 	{
-		llerrs << "Can not call this." << llendl ;
-
 		lldebugs << "LLSDRPCClientFactory::build" << llendl;
-		LLIOPipe::ptr_t service(new Client);
-		chain.push_back(service);
 		LLURLRequest* http(new LLURLRequest(LLURLRequest::HTTP_POST));
+		if(!http->isValid())
+		{
+			llwarns << "Creating LLURLRequest failed." << llendl ;
+			delete http;
+			return false;
+		}
+
+		LLIOPipe::ptr_t service(new Client);
+		chain.push_back(service);		
 		LLIOPipe::ptr_t http_pipe(http);
 		http->addHeader("Content-Type: text/llsd");
 		if(mURL.empty())
@@ -284,11 +289,17 @@ public:
 	LLXMLSDRPCClientFactory(const std::string& fixed_url) : mURL(fixed_url) {}
 	virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
 	{
-		llerrs << "who calls this?" << llendl ;
 		lldebugs << "LLXMLSDRPCClientFactory::build" << llendl;
-		LLIOPipe::ptr_t service(new Client);
-		chain.push_back(service);
+
 		LLURLRequest* http(new LLURLRequest(LLURLRequest::HTTP_POST));
+		if(!http->isValid())
+		{
+			llwarns << "Creating LLURLRequest failed." << llendl ;
+			delete http;
+			return false ;
+		}
+		LLIOPipe::ptr_t service(new Client);
+		chain.push_back(service);		
 		LLIOPipe::ptr_t http_pipe(http);
 		http->addHeader("Content-Type: text/xml");
 		if(mURL.empty())
-- 
cgit v1.2.3


From 25c21c3761d871fa7927e2a5656ed18100084454 Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Tue, 17 Jan 2012 22:56:28 -0700
Subject: add more exception handlings for llcurl fix.

---
 indra/llmessage/llcurl.cpp       | 7 ++++++-
 indra/llmessage/llurlrequest.cpp | 6 ++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 277c274f52..5edf0dc8c0 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -1036,7 +1036,12 @@ LLCurl::Easy* LLCurlRequest::allocEasy()
 	{
 		addMulti();
 	}
-	llassert_always(mActiveMulti);
+	if(!mActiveMulti)
+	{
+		return NULL ;
+	}
+
+	//llassert_always(mActiveMulti);
 	++mActiveRequestCount;
 	LLCurl::Easy* easy = mActiveMulti->allocEasy();
 	return easy;
diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index f02c636838..a16f5c7bf0 100644
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -459,6 +459,12 @@ void LLURLRequest::initialize()
 	LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
 	mState = STATE_INITIALIZED;
 	mDetail = new LLURLRequestDetail;
+
+	if(!isValid())
+	{
+		return ;
+	}
+
 	mDetail->mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1);
 	mDetail->mCurlRequest->setWriteCallback(&downCallback, (void*)this);
 	mDetail->mCurlRequest->setReadCallback(&upCallback, (void*)this);
-- 
cgit v1.2.3


From 9e6a5d721193f181c39e58fe00073bece74b081a Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Fri, 20 Jan 2012 11:55:15 -0700
Subject: fix for SH-2823 and SH-2824: LLCurl crash inside
 LLBufferArray::countAfter() and LLBufferArray::copyIntoBuffers

---
 indra/llcommon/llthread.cpp        | 15 ++++---
 indra/llcommon/llthread.h          |  1 +
 indra/llmessage/llbuffer.cpp       | 90 +++++++++++++++++++++++++++++++++++++-
 indra/llmessage/llbuffer.h         | 25 +++++++++++
 indra/llmessage/llbufferstream.cpp |  8 ++++
 indra/llmessage/llcurl.cpp         |  3 ++
 indra/llmessage/lliohttpserver.cpp |  4 +-
 indra/llmessage/lliosocket.cpp     |  3 ++
 indra/llmessage/llpumpio.cpp       |  1 +
 9 files changed, 142 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 4063cc730b..a6ad6b125c 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -337,11 +337,7 @@ LLMutex::~LLMutex()
 
 void LLMutex::lock()
 {
-#if LL_DARWIN
-	if (mLockingThread == LLThread::currentID())
-#else
-	if (mLockingThread == sThreadID)
-#endif
+	if(isSelfLocked())
 	{ //redundant lock
 		mCount++;
 		return;
@@ -398,6 +394,15 @@ bool LLMutex::isLocked()
 	}
 }
 
+bool LLMutex::isSelfLocked()
+{
+#if LL_DARWIN
+	return mLockingThread == LLThread::currentID();
+#else
+	return mLockingThread == sThreadID;
+#endif
+}
+
 U32 LLMutex::lockingThread() const
 {
 	return mLockingThread;
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index f0e0de6173..b52e70ab2e 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -151,6 +151,7 @@ public:
 	void lock();		// blocks
 	void unlock();
 	bool isLocked(); 	// non-blocking, but does do a lock/unlock so not free
+	bool isSelfLocked(); //return true if locked in a same thread
 	U32 lockingThread() const; //get ID of locking thread
 	
 protected:
diff --git a/indra/llmessage/llbuffer.cpp b/indra/llmessage/llbuffer.cpp
index 0316797f00..250cace6e9 100644
--- a/indra/llmessage/llbuffer.cpp
+++ b/indra/llmessage/llbuffer.cpp
@@ -32,6 +32,9 @@
 #include "llmath.h"
 #include "llmemtype.h"
 #include "llstl.h"
+#include "llthread.h"
+
+#define ASSERT_LLBUFFERARRAY_MUTEX_LOCKED llassert(!mMutexp || mMutexp->isSelfLocked());
 
 /** 
  * LLSegment
@@ -224,7 +227,8 @@ void LLHeapBuffer::allocate(S32 size)
  * LLBufferArray
  */
 LLBufferArray::LLBufferArray() :
-	mNextBaseChannel(0)
+	mNextBaseChannel(0),
+	mMutexp(NULL)
 {
 	LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
 }
@@ -233,6 +237,8 @@ LLBufferArray::~LLBufferArray()
 {
 	LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
 	std::for_each(mBuffers.begin(), mBuffers.end(), DeletePointer());
+
+	delete mMutexp;
 }
 
 // static
@@ -243,14 +249,57 @@ LLChannelDescriptors LLBufferArray::makeChannelConsumer(
 	return rv;
 }
 
+void LLBufferArray::lock()
+{
+	if(mMutexp)
+	{
+		mMutexp->lock() ;
+	}
+}
+
+void LLBufferArray::unlock()
+{
+	if(mMutexp)
+	{
+		mMutexp->unlock() ;
+	}
+}
+
+LLMutex* LLBufferArray::getMutex()
+{
+	return mMutexp ;
+}
+
+void LLBufferArray::setThreaded(bool threaded)
+{
+	if(threaded)
+	{
+		if(!mMutexp)
+		{
+			mMutexp = new LLMutex(NULL);
+		}
+	}
+	else
+	{
+		if(mMutexp)
+		{
+			delete mMutexp ;
+			mMutexp = NULL ;
+		}
+	}
+}
+
 LLChannelDescriptors LLBufferArray::nextChannel()
 {
 	LLChannelDescriptors rv(mNextBaseChannel++);
 	return rv;
 }
 
+//mMutexp should be locked before calling this.
 S32 LLBufferArray::capacity() const
 {
+	ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
+
 	S32 total = 0;
 	const_buffer_iterator_t iter = mBuffers.begin();
 	const_buffer_iterator_t end = mBuffers.end();
@@ -263,6 +312,8 @@ S32 LLBufferArray::capacity() const
 
 bool LLBufferArray::append(S32 channel, const U8* src, S32 len)
 {
+	LLMutexLock lock(mMutexp) ;
+
 	LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
 	std::vector<LLSegment> segments;
 	if(copyIntoBuffers(channel, src, len, segments))
@@ -273,8 +324,11 @@ bool LLBufferArray::append(S32 channel, const U8* src, S32 len)
 	return false;
 }
 
+//mMutexp should be locked before calling this.
 bool LLBufferArray::prepend(S32 channel, const U8* src, S32 len)
 {
+	ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
+
 	LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
 	std::vector<LLSegment> segments;
 	if(copyIntoBuffers(channel, src, len, segments))
@@ -293,6 +347,8 @@ bool LLBufferArray::insertAfter(
 {
 	LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
 	std::vector<LLSegment> segments;
+
+	LLMutexLock lock(mMutexp) ;
 	if(mSegments.end() != segment)
 	{
 		++segment;
@@ -305,8 +361,11 @@ bool LLBufferArray::insertAfter(
 	return false;
 }
 
+//mMutexp should be locked before calling this.
 LLBufferArray::segment_iterator_t LLBufferArray::splitAfter(U8* address)
 {
+	ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
+
 	LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
 	segment_iterator_t end = mSegments.end();
 	segment_iterator_t it = getSegment(address);
@@ -335,20 +394,26 @@ LLBufferArray::segment_iterator_t LLBufferArray::splitAfter(U8* address)
 	return rv;
 }
 							   
+//mMutexp should be locked before calling this.
 LLBufferArray::segment_iterator_t LLBufferArray::beginSegment()
 {
+	ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
 	return mSegments.begin();
 }
 
+//mMutexp should be locked before calling this.
 LLBufferArray::segment_iterator_t LLBufferArray::endSegment()
 {
+	ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
 	return mSegments.end();
 }
 
+//mMutexp should be locked before calling this.
 LLBufferArray::segment_iterator_t LLBufferArray::constructSegmentAfter(
 	U8* address,
 	LLSegment& segment)
 {
+	ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
 	LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
 	segment_iterator_t rv = mSegments.begin();
 	segment_iterator_t end = mSegments.end();
@@ -395,8 +460,10 @@ LLBufferArray::segment_iterator_t LLBufferArray::constructSegmentAfter(
 	return rv;
 }
 
+//mMutexp should be locked before calling this.
 LLBufferArray::segment_iterator_t LLBufferArray::getSegment(U8* address)
 {
+	ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
 	segment_iterator_t end = mSegments.end();
 	if(!address)
 	{
@@ -414,9 +481,11 @@ LLBufferArray::segment_iterator_t LLBufferArray::getSegment(U8* address)
 	return end;
 }
 
+//mMutexp should be locked before calling this.
 LLBufferArray::const_segment_iterator_t LLBufferArray::getSegment(
 	U8* address) const
 {
+	ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
 	const_segment_iterator_t end = mSegments.end();
 	if(!address)
 	{
@@ -466,6 +535,8 @@ S32 LLBufferArray::countAfter(S32 channel, U8* start) const
 	S32 count = 0;
 	S32 offset = 0;
 	const_segment_iterator_t it;
+
+	LLMutexLock lock(mMutexp) ;
 	const_segment_iterator_t end = mSegments.end();
 	if(start)
 	{
@@ -517,6 +588,8 @@ U8* LLBufferArray::readAfter(
 	len = 0;
 	S32 bytes_to_copy = 0;
 	const_segment_iterator_t it;
+
+	LLMutexLock lock(mMutexp) ;
 	const_segment_iterator_t end = mSegments.end();
 	if(start)
 	{
@@ -568,6 +641,7 @@ U8* LLBufferArray::seek(
 	U8* start,
 	S32 delta) const
 {
+	ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
 	LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
 	const_segment_iterator_t it;
 	const_segment_iterator_t end = mSegments.end();
@@ -709,9 +783,14 @@ U8* LLBufferArray::seek(
 	return rv;
 }
 
+//test use only
 bool LLBufferArray::takeContents(LLBufferArray& source)
 {
 	LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
+
+	LLMutexLock lock(mMutexp);
+	source.lock();
+
 	std::copy(
 		source.mBuffers.begin(),
 		source.mBuffers.end(),
@@ -723,13 +802,17 @@ bool LLBufferArray::takeContents(LLBufferArray& source)
 		std::back_insert_iterator<segment_list_t>(mSegments));
 	source.mSegments.clear();
 	source.mNextBaseChannel = 0;
+	source.unlock();
+
 	return true;
 }
 
+//mMutexp should be locked before calling this.
 LLBufferArray::segment_iterator_t LLBufferArray::makeSegment(
 	S32 channel,
 	S32 len)
 {
+	ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
 	LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
 	// start at the end of the buffers, because it is the most likely
 	// to have free space.
@@ -765,8 +848,10 @@ LLBufferArray::segment_iterator_t LLBufferArray::makeSegment(
 	return send;
 }
 
+//mMutexp should be locked before calling this.
 bool LLBufferArray::eraseSegment(const segment_iterator_t& erase_iter)
 {
+	ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
 	LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
 
 	// Find out which buffer contains the segment, and if it is found,
@@ -792,13 +877,14 @@ bool LLBufferArray::eraseSegment(const segment_iterator_t& erase_iter)
 	return rv;
 }
 
-
+//mMutexp should be locked before calling this.
 bool LLBufferArray::copyIntoBuffers(
 	S32 channel,
 	const U8* src,
 	S32 len,
 	std::vector<LLSegment>& segments)
 {
+	ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
 	LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
 	if(!src || !len) return false;
 	S32 copied = 0;
diff --git a/indra/llmessage/llbuffer.h b/indra/llmessage/llbuffer.h
index 1c42b6fbc6..ccdb9fa7ee 100644
--- a/indra/llmessage/llbuffer.h
+++ b/indra/llmessage/llbuffer.h
@@ -39,6 +39,7 @@
 #include <list>
 #include <vector>
 
+class LLMutex;
 /** 
  * @class LLChannelDescriptors
  * @brief A way simple interface to accesss channels inside a buffer
@@ -564,6 +565,29 @@ public:
 	 * @return Returns true on success.
 	 */
 	bool eraseSegment(const segment_iterator_t& iter);
+
+	/**
+	* @brief Lock the mutex if it exists
+	* This method locks mMutexp to make accessing LLBufferArray thread-safe
+	*/
+	void lock();
+
+	/**
+	* @brief Unlock the mutex if it exists
+	*/
+	void unlock();
+
+	/**
+	* @brief Return mMutexp
+	*/
+	LLMutex* getMutex();
+
+	/**
+	* @brief Set LLBufferArray to be shared across threads or not
+	* This method is to create mMutexp if is threaded.
+	* @param threaded Indicates this LLBufferArray instance is shared across threads if true.
+	*/
+	void setThreaded(bool threaded);
 	//@}
 
 protected:
@@ -595,6 +619,7 @@ protected:
 	S32 mNextBaseChannel;
 	buffer_list_t mBuffers;
 	segment_list_t mSegments;
+	LLMutex* mMutexp;
 };
 
 #endif // LL_LLBUFFER_H
diff --git a/indra/llmessage/llbufferstream.cpp b/indra/llmessage/llbufferstream.cpp
index 6257983c43..8d8ad05ad5 100644
--- a/indra/llmessage/llbufferstream.cpp
+++ b/indra/llmessage/llbufferstream.cpp
@@ -31,6 +31,7 @@
 
 #include "llbuffer.h"
 #include "llmemtype.h"
+#include "llthread.h"
 
 static const S32 DEFAULT_OUTPUT_SEGMENT_SIZE = 1024 * 4;
 
@@ -62,6 +63,7 @@ int LLBufferStreamBuf::underflow()
 		return EOF;
 	}
 
+	LLMutexLock lock(mBuffer->getMutex());
 	LLBufferArray::segment_iterator_t iter;
 	LLBufferArray::segment_iterator_t end = mBuffer->endSegment();
 	U8* last_pos = (U8*)gptr();
@@ -149,6 +151,7 @@ int LLBufferStreamBuf::overflow(int c)
 	// since we got here, we have a buffer, and we have a character to
 	// put on it.
 	LLBufferArray::segment_iterator_t it;
+	LLMutexLock lock(mBuffer->getMutex());
 	it = mBuffer->makeSegment(mChannels.out(), DEFAULT_OUTPUT_SEGMENT_SIZE);
 	if(it != mBuffer->endSegment())
 	{
@@ -210,6 +213,7 @@ int LLBufferStreamBuf::sync()
 
 	// *NOTE: I bet we could just --address if address is not NULL.
 	// Need to think about that.
+	LLMutexLock lock(mBuffer->getMutex());
 	address = mBuffer->seek(mChannels.out(), address, -1);
 	if(address)
 	{
@@ -273,6 +277,8 @@ streampos LLBufferStreamBuf::seekoff(
 			// NULL is fine
 			break;
 		}
+
+		LLMutexLock lock(mBuffer->getMutex());
 		address = mBuffer->seek(mChannels.in(), base_addr, off);
 		if(address)
 		{
@@ -304,6 +310,8 @@ streampos LLBufferStreamBuf::seekoff(
 			// NULL is fine
 			break;
 		}
+
+		LLMutexLock lock(mBuffer->getMutex());
 		address = mBuffer->seek(mChannels.out(), base_addr, off);
 		if(address)
 		{
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 5edf0dc8c0..1ab82a273b 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -228,6 +228,8 @@ LLMutex* LLCurl::Easy::sHandleMutexp = NULL ;
 //static
 CURL* LLCurl::Easy::allocEasyHandle()
 {
+	llassert(LLCurl::getCurlThread()) ;
+
 	CURL* ret = NULL;
 
 	LLMutexLock lock(sHandleMutexp) ;
@@ -489,6 +491,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
 	LLProxy::getInstance()->applyProxySettings(this);
 
 	mOutput.reset(new LLBufferArray);
+	mOutput->setThreaded(true);
 	setopt(CURLOPT_WRITEFUNCTION, (void*)&curlWriteCallback);
 	setopt(CURLOPT_WRITEDATA, (void*)this);
 
diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp
index 73e8a69085..987f386aa3 100644
--- a/indra/llmessage/lliohttpserver.cpp
+++ b/indra/llmessage/lliohttpserver.cpp
@@ -818,6 +818,8 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(
 
   			// Copy everything after mLast read to the out.
 			LLBufferArray::segment_iterator_t seg_iter;
+
+			buffer->lock();
 			seg_iter = buffer->splitAfter(mLastRead);
 			if(seg_iter != buffer->endSegment())
 			{
@@ -838,7 +840,7 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(
 				}
 #endif
 			}
-
+			buffer->unlock();
 			//
 			// *FIX: get rid of extra bytes off the end
 			//
diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp
index 54ceab3422..d5b4d45821 100644
--- a/indra/llmessage/lliosocket.cpp
+++ b/indra/llmessage/lliosocket.cpp
@@ -445,6 +445,7 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
 	// efficient - not only because writev() is better, but also
 	// because we won't have to do as much work to find the start
 	// address.
+	buffer->lock();
 	LLBufferArray::segment_iterator_t it;
 	LLBufferArray::segment_iterator_t end = buffer->endSegment();
 	LLSegment segment;
@@ -524,6 +525,8 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
 		}
 
 	}
+	buffer->unlock();
+
 	PUMP_DEBUG;
 	if(done && eos)
 	{
diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp
index 0ff300efd0..f3ef4f2684 100644
--- a/indra/llmessage/llpumpio.cpp
+++ b/indra/llmessage/llpumpio.cpp
@@ -207,6 +207,7 @@ bool LLPumpIO::addChain(const chain_t& chain, F32 timeout, bool has_curl_request
 	info.mHasCurlRequest = has_curl_request;
 	info.setTimeoutSeconds(timeout);
 	info.mData = LLIOPipe::buffer_ptr_t(new LLBufferArray);
+	info.mData->setThreaded(has_curl_request);
 	LLLinkInfo link;
 #if LL_DEBUG_PIPE_TYPE_IN_PUMP
 	lldebugs << "LLPumpIO::addChain() " << chain[0] << " '"
-- 
cgit v1.2.3


From 1316f3313066beef74729c2be5a8d142d185161d Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Wed, 25 Jan 2012 16:01:56 -0700
Subject: fix for SH-2904: textures remain stuck in HTP state

---
 indra/llmessage/llcurl.cpp | 11 +++++++++++
 indra/llmessage/llcurl.h   |  2 ++
 2 files changed, 13 insertions(+)

(limited to 'indra')

diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 1ab82a273b..32a9cd061f 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -91,6 +91,7 @@ std::string LLCurl::sCAFile;
 LLCurlThread* LLCurl::sCurlThread = NULL ;
 LLMutex* LLCurl::sHandleMutexp = NULL ;
 S32      LLCurl::sTotalHandles = 0 ;
+bool     LLCurl::sNotQuitting = true;
 
 void check_curl_code(CURLcode code)
 {
@@ -319,6 +320,14 @@ LLCurl::Easy::~Easy()
 	--gCurlEasyCount;
 	curl_slist_free_all(mHeaders);
 	for_each(mStrings.begin(), mStrings.end(), DeletePointerArray());
+
+	if (mResponder && LLCurl::sNotQuitting) //aborted
+	{	
+		std::string reason("Request timeout, aborted.") ;
+		mResponder->completedRaw(408, //HTTP_REQUEST_TIME_OUT, timeout, abort
+			reason, mChannels, mOutput);		
+	}
+	mResponder = NULL;
 }
 
 void LLCurl::Easy::resetState()
@@ -1462,6 +1471,8 @@ void LLCurl::initClass(bool multi_threaded)
 
 void LLCurl::cleanupClass()
 {
+	sNotQuitting = false; //set quitting
+
 	//shut down curl thread
 	while(1)
 	{
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index 2b23ac9763..7d2340a6cb 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -197,6 +197,8 @@ private:
 
 	static LLMutex* sHandleMutexp ;
 	static S32      sTotalHandles ;
+public:
+	static bool     sNotQuitting;
 };
 
 class LLCurl::Easy
-- 
cgit v1.2.3


From 717a6f3306d9382ea252c3e0f243b785c9cae15a Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Wed, 25 Jan 2012 18:27:40 -0700
Subject: Introduce two new parameters "CurlUseMultipleThreads" and
 "CurlRequestTimeOut" for QA to test Curl.

---
 indra/llmessage/llcurl.cpp              | 18 ++++++++++--------
 indra/llmessage/llcurl.h                |  4 +++-
 indra/newview/app_settings/settings.xml | 22 ++++++++++++++++++++++
 indra/newview/llappviewer.cpp           |  4 +++-
 4 files changed, 38 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 32a9cd061f..3bcaffc275 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -75,9 +75,6 @@ static const S32 MULTI_PERFORM_CALL_REPEAT	= 5;
 static const S32 CURL_REQUEST_TIMEOUT = 30; // seconds per operation
 static const S32 MAX_ACTIVE_REQUEST_COUNT = 100;
 
-static const F32 DEFAULT_MULTI_IDLE_TIME = 120.0f ; //seconds
-static const S32 MAX_NUM_OF_HANDLES = 256 ; //max number of handles, (multi handles and easy handles combined).
-
 // DEBUG //
 S32 gCurlEasyCount = 0;
 S32 gCurlMultiCount = 0;
@@ -92,6 +89,8 @@ LLCurlThread* LLCurl::sCurlThread = NULL ;
 LLMutex* LLCurl::sHandleMutexp = NULL ;
 S32      LLCurl::sTotalHandles = 0 ;
 bool     LLCurl::sNotQuitting = true;
+F32      LLCurl::sCurlRequestTimeOut = 120.f; //seonds
+S32      LLCurl::sMaxHandles = 256; //max number of handles, (multi handles and easy handles combined).
 
 void check_curl_code(CURLcode code)
 {
@@ -573,9 +572,9 @@ LLCurl::Multi::Multi(F32 idle_time_out)
 		LLCurl::getCurlThread()->addMulti(this) ;
 
 		mIdleTimeOut = idle_time_out ;
-		if(mIdleTimeOut < DEFAULT_MULTI_IDLE_TIME)
+		if(mIdleTimeOut < LLCurl::sCurlRequestTimeOut)
 		{
-			mIdleTimeOut = DEFAULT_MULTI_IDLE_TIME ;
+			mIdleTimeOut = LLCurl::sCurlRequestTimeOut ;
 		}
 
 		++gCurlMultiCount;
@@ -1442,8 +1441,11 @@ unsigned long LLCurl::ssl_thread_id(void)
 }
 #endif
 
-void LLCurl::initClass(bool multi_threaded)
+void LLCurl::initClass(F32 curl_reuest_timeout, S32 max_number_handles, bool multi_threaded)
 {
+	sCurlRequestTimeOut = curl_reuest_timeout ; //seconds
+	sMaxHandles = max_number_handles ; //max number of handles, (multi handles and easy handles combined).
+
 	// Do not change this "unless you are familiar with and mean to control 
 	// internal operations of libcurl"
 	// - http://curl.haxx.se/libcurl/c/curl_global_init.html
@@ -1512,7 +1514,7 @@ CURLM* LLCurl::newMultiHandle()
 {
 	LLMutexLock lock(sHandleMutexp) ;
 
-	if(sTotalHandles + 1 > MAX_NUM_OF_HANDLES)
+	if(sTotalHandles + 1 > sMaxHandles)
 	{
 		llwarns << "no more handles available." << llendl ;
 		return NULL ; //failed
@@ -1545,7 +1547,7 @@ CURL*  LLCurl::newEasyHandle()
 {
 	LLMutexLock lock(sHandleMutexp) ;
 
-	if(sTotalHandles + 1 > MAX_NUM_OF_HANDLES)
+	if(sTotalHandles + 1 > sMaxHandles)
 	{
 		llwarns << "no more handles available." << llendl ;
 		return NULL ; //failed
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index 7d2340a6cb..fd664c0fa1 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -163,7 +163,7 @@ public:
 	/**
 	 * @ brief Initialize LLCurl class
 	 */
-	static void initClass(bool multi_threaded = false);
+	static void initClass(F32 curl_reuest_timeout = 120.f, S32 max_number_handles = 256, bool multi_threaded = false);
 
 	/**
 	 * @ brief Cleanup LLCurl class
@@ -197,8 +197,10 @@ private:
 
 	static LLMutex* sHandleMutexp ;
 	static S32      sTotalHandles ;
+	static S32      sMaxHandles;
 public:
 	static bool     sNotQuitting;
+	static F32      sCurlRequestTimeOut;	
 };
 
 class LLCurl::Easy
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 1ea623791d..a29d5d2985 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1828,6 +1828,28 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+  <key>CurlMaximumNumberOfHandles</key>
+  <map>
+    <key>Comment</key>
+    <string>Maximum number of handles curl can use (requires restart)</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>S32</string>
+    <key>Value</key>
+    <integer>256</integer>
+  </map>
+  <key>CurlRequestTimeOut</key>
+  <map>
+    <key>Comment</key>
+    <string>Max idle time of a curl request before killed (requires restart)</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>120.0</real>
+  </map>
   <key>CurlUseMultipleThreads</key>
   <map>
     <key>Comment</key>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 40136adbc9..4fc306e61d 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -720,7 +720,9 @@ bool LLAppViewer::init()
 
     // *NOTE:Mani - LLCurl::initClass is not thread safe. 
     // Called before threads are created.
-    LLCurl::initClass(gSavedSettings.getBOOL("CurlUseMultipleThreads"));
+    LLCurl::initClass(gSavedSettings.getF32("CurlRequestTimeOut"), 
+						gSavedSettings.getS32("CurlMaximumNumberOfHandles"), 
+						gSavedSettings.getBOOL("CurlUseMultipleThreads"));
 	LL_INFOS("InitInfo") << "LLCurl initialized." << LL_ENDL ;
 
     LLMachineID::init();
-- 
cgit v1.2.3


From b5a1d08347a88736a67e0dc0e0e6069952be7e7a Mon Sep 17 00:00:00 2001
From: Todd Stinson <stinson@lindenlab.com>
Date: Mon, 30 Jan 2012 12:24:31 -0800
Subject: PATH-187: Resolving an issue where in a particular scenario the edit
 fields were not being disabled when nothing was selected.

---
 indra/newview/llfloaterpathfindinglinksets.cpp | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterpathfindinglinksets.cpp b/indra/newview/llfloaterpathfindinglinksets.cpp
index 571c4a8427..3edb4e5c73 100644
--- a/indra/newview/llfloaterpathfindinglinksets.cpp
+++ b/indra/newview/llfloaterpathfindinglinksets.cpp
@@ -372,6 +372,7 @@ void LLFloaterPathfindingLinksets::setMessagingState(EMessagingState pMessagingS
 {
 	mMessagingState = pMessagingState;
 	updateLinksetsStatusMessage();
+	updateEditFields();
 }
 
 void LLFloaterPathfindingLinksets::onApplyFiltersClicked()
@@ -524,6 +525,7 @@ void LLFloaterPathfindingLinksets::updateLinksetsList()
 
 	mLinksetsScrollList->selectMultiple(selectedUUIDs);
 	updateLinksetsStatusMessage();
+	updateEditFields();
 }
 
 void LLFloaterPathfindingLinksets::selectAllLinksets()
-- 
cgit v1.2.3


From 0e609cc95b08c28bd51f5ab48160fd93df7a6b28 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Mon, 30 Jan 2012 16:45:50 -0500
Subject: increment viewer version to 3.2.9

---
 indra/llcommon/llversionviewer.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
index 99ab053b25..27cdfcaa4e 100644
--- a/indra/llcommon/llversionviewer.h
+++ b/indra/llcommon/llversionviewer.h
@@ -29,7 +29,7 @@
 
 const S32 LL_VERSION_MAJOR = 3;
 const S32 LL_VERSION_MINOR = 2;
-const S32 LL_VERSION_PATCH = 8;
+const S32 LL_VERSION_PATCH = 9;
 const S32 LL_VERSION_BUILD = 0;
 
 const char * const LL_CHANNEL = "Second Life Developer";
-- 
cgit v1.2.3


From de6ae690b5315307b59b1a2ac722700c3839e4ba Mon Sep 17 00:00:00 2001
From: Todd Stinson <stinson@lindenlab.com>
Date: Mon, 30 Jan 2012 16:33:41 -0800
Subject: PATH-187: Consolidating field names for the cap service into local
 defines.

---
 indra/newview/llfilteredpathfindinglinksets.cpp |  24 ++--
 indra/newview/llfilteredpathfindinglinksets.h   |   6 +-
 indra/newview/llfloaterpathfindinglinksets.cpp  |   2 +-
 indra/newview/llpathfindinglinkset.cpp          | 158 +++++++++++++-----------
 indra/newview/llpathfindinglinkset.h            |   4 +-
 5 files changed, 103 insertions(+), 91 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfilteredpathfindinglinksets.cpp b/indra/newview/llfilteredpathfindinglinksets.cpp
index c956a5752b..aaff2bcc68 100644
--- a/indra/newview/llfilteredpathfindinglinksets.cpp
+++ b/indra/newview/llfilteredpathfindinglinksets.cpp
@@ -122,7 +122,7 @@ LLFilteredPathfindingLinksets::LLFilteredPathfindingLinksets()
 {
 }
 
-LLFilteredPathfindingLinksets::LLFilteredPathfindingLinksets(const LLSD& pNavMeshData)
+LLFilteredPathfindingLinksets::LLFilteredPathfindingLinksets(const LLSD& pLinksetItems)
 	: mAllLinksets(),
 	mFilteredLinksets(),
 	mIsFiltersDirty(false),
@@ -132,7 +132,7 @@ LLFilteredPathfindingLinksets::LLFilteredPathfindingLinksets(const LLSD& pNavMes
 	mIsObstacleFilter(true),
 	mIsIgnoredFilter(true)
 {
-	setPathfindingLinksets(pNavMeshData);
+	setPathfindingLinksets(pLinksetItems);
 }
 
 LLFilteredPathfindingLinksets::LLFilteredPathfindingLinksets(const LLFilteredPathfindingLinksets& pOther)
@@ -152,15 +152,15 @@ LLFilteredPathfindingLinksets::~LLFilteredPathfindingLinksets()
 	clearPathfindingLinksets();
 }
 
-void LLFilteredPathfindingLinksets::setPathfindingLinksets(const LLSD& pNavMeshData)
+void LLFilteredPathfindingLinksets::setPathfindingLinksets(const LLSD& pLinksetItems)
 {
 	clearPathfindingLinksets();
 
-	for (LLSD::map_const_iterator navMeshDataIter = pNavMeshData.beginMap();
-		navMeshDataIter != pNavMeshData.endMap(); ++navMeshDataIter)
+	for (LLSD::map_const_iterator linksetItemIter = pLinksetItems.beginMap();
+		linksetItemIter != pLinksetItems.endMap(); ++linksetItemIter)
 	{
-		const std::string& uuid(navMeshDataIter->first);
-		const LLSD& linksetData = navMeshDataIter->second;
+		const std::string& uuid(linksetItemIter->first);
+		const LLSD& linksetData = linksetItemIter->second;
 		LLPathfindingLinkset linkset(uuid, linksetData);
 
 		mAllLinksets.insert(std::pair<std::string, LLPathfindingLinkset>(uuid, linkset));
@@ -169,13 +169,13 @@ void LLFilteredPathfindingLinksets::setPathfindingLinksets(const LLSD& pNavMeshD
 	mIsFiltersDirty = true;
 }
 
-void LLFilteredPathfindingLinksets::updatePathfindingLinksets(const LLSD& pNavMeshData)
+void LLFilteredPathfindingLinksets::updatePathfindingLinksets(const LLSD& pLinksetItems)
 {
-	for (LLSD::map_const_iterator navMeshDataIter = pNavMeshData.beginMap();
-		navMeshDataIter != pNavMeshData.endMap(); ++navMeshDataIter)
+	for (LLSD::map_const_iterator linksetItemIter = pLinksetItems.beginMap();
+		linksetItemIter != pLinksetItems.endMap(); ++linksetItemIter)
 	{
-		const std::string& uuid(navMeshDataIter->first);
-		const LLSD& linksetData = navMeshDataIter->second;
+		const std::string& uuid(linksetItemIter->first);
+		const LLSD& linksetData = linksetItemIter->second;
 		LLPathfindingLinkset linkset(uuid, linksetData);
 
 		PathfindingLinksetMap::iterator linksetIter = mAllLinksets.find(uuid);
diff --git a/indra/newview/llfilteredpathfindinglinksets.h b/indra/newview/llfilteredpathfindinglinksets.h
index afd2b2b01d..de9b3a5e15 100644
--- a/indra/newview/llfilteredpathfindinglinksets.h
+++ b/indra/newview/llfilteredpathfindinglinksets.h
@@ -61,12 +61,12 @@ public:
 	typedef std::map<std::string, LLPathfindingLinkset> PathfindingLinksetMap;
 
 	LLFilteredPathfindingLinksets();
-	LLFilteredPathfindingLinksets(const LLSD& pNavMeshData);
+	LLFilteredPathfindingLinksets(const LLSD& pLinksetItems);
 	LLFilteredPathfindingLinksets(const LLFilteredPathfindingLinksets& pOther);
 	virtual ~LLFilteredPathfindingLinksets();
 
-	void                         setPathfindingLinksets(const LLSD& pNavMeshData);
-	void                         updatePathfindingLinksets(const LLSD& pNavMeshData);
+	void                         setPathfindingLinksets(const LLSD& pLinksetItems);
+	void                         updatePathfindingLinksets(const LLSD& pLinksetItems);
 	void                         clearPathfindingLinksets();
 
 	const PathfindingLinksetMap& getAllLinksets() const;
diff --git a/indra/newview/llfloaterpathfindinglinksets.cpp b/indra/newview/llfloaterpathfindinglinksets.cpp
index 3edb4e5c73..4d3581fc60 100644
--- a/indra/newview/llfloaterpathfindinglinksets.cpp
+++ b/indra/newview/llfloaterpathfindinglinksets.cpp
@@ -672,7 +672,7 @@ void LLFloaterPathfindingLinksets::applyEditFields()
 			const LLFilteredPathfindingLinksets::PathfindingLinksetMap::const_iterator linksetIter = linksetsMap.find(uuid.asString());
 			const LLPathfindingLinkset &linkset = linksetIter->second;
 
-			LLSD itemData = linkset.getAlteredFields(pathState, aValue, bValue, cValue, dValue, isPhantom);
+			LLSD itemData = linkset.encodeAlteredFields(pathState, aValue, bValue, cValue, dValue, isPhantom);
 
 			if (!itemData.isUndefined())
 			{
diff --git a/indra/newview/llpathfindinglinkset.cpp b/indra/newview/llpathfindinglinkset.cpp
index bfe851d8ee..daa308f862 100644
--- a/indra/newview/llpathfindinglinkset.cpp
+++ b/indra/newview/llpathfindinglinkset.cpp
@@ -31,6 +31,18 @@
 #include "v3math.h"
 #include "lluuid.h"
 
+#define LINKSET_NAME_FIELD          "name"
+#define LINKSET_DESCRIPTION_FIELD   "description"
+#define LINKSET_LAND_IMPACT_FIELD   "landimpact"
+#define LINKSET_PERMANENT_FIELD     "permanent"
+#define LINKSET_WALKABLE_FIELD      "walkable"
+#define LINKSET_PHANTOM_FIELD       "phantom"
+#define LINKSET_WALKABILITY_A_FIELD "A"
+#define LINKSET_WALKABILITY_B_FIELD "B"
+#define LINKSET_WALKABILITY_C_FIELD "C"
+#define LINKSET_WALKABILITY_D_FIELD "D"
+#define LINKSET_POSITION_FIELD      "position"
+
 //---------------------------------------------------------------------------
 // LLPathfindingLinkset
 //---------------------------------------------------------------------------
@@ -38,7 +50,7 @@
 const S32 LLPathfindingLinkset::MIN_WALKABILITY_VALUE(0);
 const S32 LLPathfindingLinkset::MAX_WALKABILITY_VALUE(100);
 
-LLPathfindingLinkset::LLPathfindingLinkset(const std::string &pUUID, const LLSD& pNavMeshItem)
+LLPathfindingLinkset::LLPathfindingLinkset(const std::string &pUUID, const LLSD& pLinksetItem)
 	: mUUID(pUUID),
 	mName(),
 	mDescription(),
@@ -54,107 +66,107 @@ LLPathfindingLinkset::LLPathfindingLinkset(const std::string &pUUID, const LLSD&
 	mWalkabilityCoefficientC(MIN_WALKABILITY_VALUE),
 	mWalkabilityCoefficientD(MIN_WALKABILITY_VALUE)
 {
-	llassert(pNavMeshItem.has("name"));
-	llassert(pNavMeshItem.get("name").isString());
-	mName = pNavMeshItem.get("name").asString();
+	llassert(pLinksetItem.has(LINKSET_NAME_FIELD));
+	llassert(pLinksetItem.get(LINKSET_NAME_FIELD).isString());
+	mName = pLinksetItem.get(LINKSET_NAME_FIELD).asString();
 
-	llassert(pNavMeshItem.has("description"));
-	llassert(pNavMeshItem.get("description").isString());
-	mDescription = pNavMeshItem.get("description").asString();
+	llassert(pLinksetItem.has(LINKSET_DESCRIPTION_FIELD));
+	llassert(pLinksetItem.get(LINKSET_DESCRIPTION_FIELD).isString());
+	mDescription = pLinksetItem.get(LINKSET_DESCRIPTION_FIELD).asString();
 
-	llassert(pNavMeshItem.has("landimpact"));
-	llassert(pNavMeshItem.get("landimpact").isInteger());
-	llassert(pNavMeshItem.get("landimpact").asInteger() >= 0);
-	mLandImpact = pNavMeshItem.get("landimpact").asInteger();
+	llassert(pLinksetItem.has(LINKSET_LAND_IMPACT_FIELD));
+	llassert(pLinksetItem.get(LINKSET_LAND_IMPACT_FIELD).isInteger());
+	llassert(pLinksetItem.get(LINKSET_LAND_IMPACT_FIELD).asInteger() >= 0);
+	mLandImpact = pLinksetItem.get(LINKSET_LAND_IMPACT_FIELD).asInteger();
 
-	llassert(pNavMeshItem.has("permanent"));
-	llassert(pNavMeshItem.get("permanent").isBoolean());
-	bool isPermanent = pNavMeshItem.get("permanent").asBoolean();
+	llassert(pLinksetItem.has(LINKSET_PERMANENT_FIELD));
+	llassert(pLinksetItem.get(LINKSET_PERMANENT_FIELD).isBoolean());
+	bool isPermanent = pLinksetItem.get(LINKSET_PERMANENT_FIELD).asBoolean();
 
-	llassert(pNavMeshItem.has("walkable"));
-	llassert(pNavMeshItem.get("walkable").isBoolean());
-	bool isWalkable = pNavMeshItem.get("walkable").asBoolean();
+	llassert(pLinksetItem.has(LINKSET_WALKABLE_FIELD));
+	llassert(pLinksetItem.get(LINKSET_WALKABLE_FIELD).isBoolean());
+	bool isWalkable = pLinksetItem.get(LINKSET_WALKABLE_FIELD).asBoolean();
 
 	mPathState = getPathState(isPermanent, isWalkable);
 
-	llassert(pNavMeshItem.has("phantom"));
-	llassert(pNavMeshItem.get("phantom").isBoolean());
-	mIsPhantom = pNavMeshItem.get("phantom").asBoolean();
+	llassert(pLinksetItem.has(LINKSET_PHANTOM_FIELD));
+	llassert(pLinksetItem.get(LINKSET_PHANTOM_FIELD).isBoolean());
+	mIsPhantom = pLinksetItem.get(LINKSET_PHANTOM_FIELD).asBoolean();
 
-	llassert(pNavMeshItem.has("A"));
+	llassert(pLinksetItem.has(LINKSET_WALKABILITY_A_FIELD));
 #ifdef XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
-	mIsWalkabilityCoefficientsF32 = pNavMeshItem.get("A").isReal();
+	mIsWalkabilityCoefficientsF32 = pLinksetItem.get(LINKSET_WALKABILITY_A_FIELD).isReal();
 	if (mIsWalkabilityCoefficientsF32)
 	{
 		// Old server-side storage was real
-		mWalkabilityCoefficientA = llround(pNavMeshItem.get("A").asReal() * 100.0f);
+		mWalkabilityCoefficientA = llround(pLinksetItem.get(LINKSET_WALKABILITY_A_FIELD).asReal() * 100.0f);
 
-		llassert(pNavMeshItem.has("B"));
-		llassert(pNavMeshItem.get("B").isReal());
-		mWalkabilityCoefficientB = llround(pNavMeshItem.get("B").asReal() * 100.0f);
+		llassert(pLinksetItem.has(LINKSET_WALKABILITY_B_FIELD));
+		llassert(pLinksetItem.get(LINKSET_WALKABILITY_B_FIELD).isReal());
+		mWalkabilityCoefficientB = llround(pLinksetItem.get(LINKSET_WALKABILITY_B_FIELD).asReal() * 100.0f);
 
-		llassert(pNavMeshItem.has("C"));
-		llassert(pNavMeshItem.get("C").isReal());
-		mWalkabilityCoefficientC = llround(pNavMeshItem.get("C").asReal() * 100.0f);
+		llassert(pLinksetItem.has(LINKSET_WALKABILITY_C_FIELD));
+		llassert(pLinksetItem.get(LINKSET_WALKABILITY_C_FIELD).isReal());
+		mWalkabilityCoefficientC = llround(pLinksetItem.get(LINKSET_WALKABILITY_C_FIELD).asReal() * 100.0f);
 
-		llassert(pNavMeshItem.has("D"));
-		llassert(pNavMeshItem.get("D").isReal());
-		mWalkabilityCoefficientD = llround(pNavMeshItem.get("D").asReal() * 100.0f);
+		llassert(pLinksetItem.has(LINKSET_WALKABILITY_D_FIELD));
+		llassert(pLinksetItem.get(LINKSET_WALKABILITY_D_FIELD).isReal());
+		mWalkabilityCoefficientD = llround(pLinksetItem.get(LINKSET_WALKABILITY_D_FIELD).asReal() * 100.0f);
 	}
 	else
 	{
 		// New server-side storage will be integer
-		llassert(pNavMeshItem.get("A").isInteger());
-		mWalkabilityCoefficientA = pNavMeshItem.get("A").asInteger();
+		llassert(pLinksetItem.get(LINKSET_WALKABILITY_A_FIELD).isInteger());
+		mWalkabilityCoefficientA = pLinksetItem.get(LINKSET_WALKABILITY_A_FIELD).asInteger();
 		llassert(mWalkabilityCoefficientA >= MIN_WALKABILITY_VALUE);
 		llassert(mWalkabilityCoefficientA <= MAX_WALKABILITY_VALUE);
 
-		llassert(pNavMeshItem.has("B"));
-		llassert(pNavMeshItem.get("B").isInteger());
-		mWalkabilityCoefficientB = pNavMeshItem.get("B").asInteger();
+		llassert(pLinksetItem.has(LINKSET_WALKABILITY_B_FIELD));
+		llassert(pLinksetItem.get(LINKSET_WALKABILITY_B_FIELD).isInteger());
+		mWalkabilityCoefficientB = pLinksetItem.get(LINKSET_WALKABILITY_B_FIELD).asInteger();
 		llassert(mWalkabilityCoefficientB >= MIN_WALKABILITY_VALUE);
 		llassert(mWalkabilityCoefficientB <= MAX_WALKABILITY_VALUE);
 
-		llassert(pNavMeshItem.has("C"));
-		llassert(pNavMeshItem.get("C").isInteger());
-		mWalkabilityCoefficientC = pNavMeshItem.get("C").asInteger();
+		llassert(pLinksetItem.has(LINKSET_WALKABILITY_C_FIELD));
+		llassert(pLinksetItem.get(LINKSET_WALKABILITY_C_FIELD).isInteger());
+		mWalkabilityCoefficientC = pLinksetItem.get(LINKSET_WALKABILITY_C_FIELD).asInteger();
 		llassert(mWalkabilityCoefficientC >= MIN_WALKABILITY_VALUE);
 		llassert(mWalkabilityCoefficientC <= MAX_WALKABILITY_VALUE);
 
-		llassert(pNavMeshItem.has("D"));
-		llassert(pNavMeshItem.get("D").isInteger());
-		mWalkabilityCoefficientD = pNavMeshItem.get("D").asInteger();
+		llassert(pLinksetItem.has(LINKSET_WALKABILITY_D_FIELD));
+		llassert(pLinksetItem.get(LINKSET_WALKABILITY_D_FIELD).isInteger());
+		mWalkabilityCoefficientD = pLinksetItem.get(LINKSET_WALKABILITY_D_FIELD).asInteger();
 		llassert(mWalkabilityCoefficientD >= MIN_WALKABILITY_VALUE);
 		llassert(mWalkabilityCoefficientD <= MAX_WALKABILITY_VALUE);
 	}
 #else // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
-	llassert(pNavMeshItem.get("A").isInteger());
-	mWalkabilityCoefficientA = pNavMeshItem.get("A").asInteger();
+	llassert(pLinksetItem.get(LINKSET_WALKABILITY_A_FIELD).isInteger());
+	mWalkabilityCoefficientA = pLinksetItem.get(LINKSET_WALKABILITY_A_FIELD).asInteger();
 	llassert(mWalkabilityCoefficientA >= MIN_WALKABILITY_VALUE);
 	llassert(mWalkabilityCoefficientA <= MAX_WALKABILITY_VALUE);
 
-	llassert(pNavMeshItem.has("B"));
-	llassert(pNavMeshItem.get("B").isInteger());
-	mWalkabilityCoefficientB = pNavMeshItem.get("B").asInteger();
+	llassert(pLinksetItem.has(LINKSET_WALKABILITY_B_FIELD));
+	llassert(pLinksetItem.get(LINKSET_WALKABILITY_B_FIELD).isInteger());
+	mWalkabilityCoefficientB = pLinksetItem.get(LINKSET_WALKABILITY_B_FIELD).asInteger();
 	llassert(mWalkabilityCoefficientB >= MIN_WALKABILITY_VALUE);
 	llassert(mWalkabilityCoefficientB <= MAX_WALKABILITY_VALUE);
 
-	llassert(pNavMeshItem.has("C"));
-	llassert(pNavMeshItem.get("C").isInteger());
-	mWalkabilityCoefficientC = pNavMeshItem.get("C").asInteger();
+	llassert(pLinksetItem.has(LINKSET_WALKABILITY_C_FIELD));
+	llassert(pLinksetItem.get(LINKSET_WALKABILITY_C_FIELD).isInteger());
+	mWalkabilityCoefficientC = pLinksetItem.get(LINKSET_WALKABILITY_C_FIELD).asInteger();
 	llassert(mWalkabilityCoefficientC >= MIN_WALKABILITY_VALUE);
 	llassert(mWalkabilityCoefficientC <= MAX_WALKABILITY_VALUE);
 
-	llassert(pNavMeshItem.has("D"));
-	llassert(pNavMeshItem.get("D").isInteger());
-	mWalkabilityCoefficientD = pNavMeshItem.get("D").asInteger();
+	llassert(pLinksetItem.has(LINKSET_WALKABILITY_D_FIELD));
+	llassert(pLinksetItem.get(LINKSET_WALKABILITY_D_FIELD).isInteger());
+	mWalkabilityCoefficientD = pLinksetItem.get(LINKSET_WALKABILITY_D_FIELD).asInteger();
 	llassert(mWalkabilityCoefficientD >= MIN_WALKABILITY_VALUE);
 	llassert(mWalkabilityCoefficientD <= MAX_WALKABILITY_VALUE);
 #endif // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
 
-	llassert(pNavMeshItem.has("position"));
-	llassert(pNavMeshItem.get("position").isArray());
-	mLocation.setValue(pNavMeshItem.get("position"));
+	llassert(pLinksetItem.has(LINKSET_POSITION_FIELD));
+	llassert(pLinksetItem.get(LINKSET_POSITION_FIELD).isArray());
+	mLocation.setValue(pLinksetItem.get(LINKSET_POSITION_FIELD));
 }
 
 LLPathfindingLinkset::LLPathfindingLinkset(const LLPathfindingLinkset& pOther)
@@ -269,75 +281,75 @@ void LLPathfindingLinkset::setWalkabilityCoefficientD(S32 pD)
 	mWalkabilityCoefficientD = llclamp(pD, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
 }
 
-LLSD LLPathfindingLinkset::getAlteredFields(EPathState pPathState, S32 pA, S32 pB, S32 pC, S32 pD, BOOL pIsPhantom) const
+LLSD LLPathfindingLinkset::encodeAlteredFields(EPathState pPathState, S32 pA, S32 pB, S32 pC, S32 pD, BOOL pIsPhantom) const
 {
 	LLSD itemData;
 
 	if (mPathState != pPathState)
 	{
-		itemData["permanent"] = static_cast<bool>(LLPathfindingLinkset::isPermanent(pPathState));
-		itemData["walkable"] = static_cast<bool>(LLPathfindingLinkset::isWalkable(pPathState));
+		itemData[LINKSET_PERMANENT_FIELD] = static_cast<bool>(LLPathfindingLinkset::isPermanent(pPathState));
+		itemData[LINKSET_WALKABLE_FIELD] = static_cast<bool>(LLPathfindingLinkset::isWalkable(pPathState));
 	}
 #ifdef XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
 	if (mIsWalkabilityCoefficientsF32)
 	{
 		if (mWalkabilityCoefficientA != pA)
 		{
-			itemData["A"] = llclamp(static_cast<F32>(pA) / 100.0f, 0.0f, 1.0f);
+			itemData[LINKSET_WALKABILITY_A_FIELD] = llclamp(static_cast<F32>(pA) / 100.0f, 0.0f, 1.0f);
 		}
 		if (mWalkabilityCoefficientB != pB)
 		{
-			itemData["B"] = llclamp(static_cast<F32>(pB) / 100.0f, 0.0f, 1.0f);
+			itemData[LINKSET_WALKABILITY_B_FIELD] = llclamp(static_cast<F32>(pB) / 100.0f, 0.0f, 1.0f);
 		}
 		if (mWalkabilityCoefficientC != pC)
 		{
-			itemData["C"] = llclamp(static_cast<F32>(pC) / 100.0f, 0.0f, 1.0f);
+			itemData[LINKSET_WALKABILITY_C_FIELD] = llclamp(static_cast<F32>(pC) / 100.0f, 0.0f, 1.0f);
 		}
 		if (mWalkabilityCoefficientD != pD)
 		{
-			itemData["D"] = llclamp(static_cast<F32>(pD) / 100.0f, 0.0f, 1.0f);
+			itemData[LINKSET_WALKABILITY_D_FIELD] = llclamp(static_cast<F32>(pD) / 100.0f, 0.0f, 1.0f);
 		}
 	}
 	else
 	{
 		if (mWalkabilityCoefficientA != pA)
 		{
-			itemData["A"] = llclamp(pA, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+			itemData[LINKSET_WALKABILITY_A_FIELD] = llclamp(pA, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
 		}
 		if (mWalkabilityCoefficientB != pB)
 		{
-			itemData["B"] = llclamp(pB, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+			itemData[LINKSET_WALKABILITY_B_FIELD] = llclamp(pB, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
 		}
 		if (mWalkabilityCoefficientC != pC)
 		{
-			itemData["C"] = llclamp(pC, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+			itemData[LINKSET_WALKABILITY_C_FIELD] = llclamp(pC, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
 		}
 		if (mWalkabilityCoefficientD != pD)
 		{
-			itemData["D"] = llclamp(pD, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+			itemData[LINKSET_WALKABILITY_D_FIELD] = llclamp(pD, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
 		}
 	}
 #else // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
 	if (mWalkabilityCoefficientA != pA)
 	{
-		itemData["A"] = llclamp(pA, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+		itemData[LINKSET_WALKABILITY_A_FIELD] = llclamp(pA, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
 	}
 	if (mWalkabilityCoefficientB != pB)
 	{
-		itemData["B"] = llclamp(pB, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+		itemData[LINKSET_WALKABILITY_B_FIELD] = llclamp(pB, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
 	}
 	if (mWalkabilityCoefficientC != pC)
 	{
-		itemData["C"] = llclamp(pC, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+		itemData[LINKSET_WALKABILITY_C_FIELD] = llclamp(pC, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
 	}
 	if (mWalkabilityCoefficientD != pD)
 	{
-		itemData["D"] = llclamp(pD, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+		itemData[LINKSET_WALKABILITY_D_FIELD] = llclamp(pD, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
 	}
 #endif // XXX_STINSON_WALKABILITY_COEFFICIENTS_TYPE_CHANGE
 	if (mIsPhantom != pIsPhantom)
 	{
-		itemData["phantom"] = static_cast<bool>(pIsPhantom);
+		itemData[LINKSET_PHANTOM_FIELD] = static_cast<bool>(pIsPhantom);
 	}
 
 	return itemData;
diff --git a/indra/newview/llpathfindinglinkset.h b/indra/newview/llpathfindinglinkset.h
index c6165907d0..d4e58874eb 100644
--- a/indra/newview/llpathfindinglinkset.h
+++ b/indra/newview/llpathfindinglinkset.h
@@ -47,7 +47,7 @@ public:
 		kIgnored
 	} EPathState;
 
-	LLPathfindingLinkset(const std::string &pUUID, const LLSD &pNavMeshItem);
+	LLPathfindingLinkset(const std::string &pUUID, const LLSD &pLinksetItem);
 	LLPathfindingLinkset(const LLPathfindingLinkset& pOther);
 	virtual ~LLPathfindingLinkset();
 
@@ -81,7 +81,7 @@ public:
 	inline S32                getWalkabilityCoefficientD() const  {return mWalkabilityCoefficientD;};
 	void                      setWalkabilityCoefficientD(S32 pD);
 
-	LLSD                      getAlteredFields(EPathState pPathState, S32 pA, S32 pB, S32 pC, S32 pD, BOOL pIsPhantom) const;
+	LLSD                      encodeAlteredFields(EPathState pPathState, S32 pA, S32 pB, S32 pC, S32 pD, BOOL pIsPhantom) const;
 
 protected:
 
-- 
cgit v1.2.3