Commits

davep committed 538b825 Merge

merge

Comments (0)

Files changed (37)

 80f3e30d8aa4d8f674a48bd742aaa6d8e9eae0b5 3.2.3-start
 a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release
 a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release
+3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-start

indra/llcommon/llmemory.cpp

 	if(update)
 	{
 		updateMemoryInfo() ;
+		LLPrivateMemoryPoolManager::getInstance()->updateStatistics() ;
 	}
 
 	llinfos << "Current allocated physical memory(KB): " << sAllocatedMemInKB << llendl ;

indra/llcommon/llversionviewer.h

 
 const S32 LL_VERSION_MAJOR = 3;
 const S32 LL_VERSION_MINOR = 2;
-const S32 LL_VERSION_PATCH = 4;
+const S32 LL_VERSION_PATCH = 5;
 const S32 LL_VERSION_BUILD = 0;
 
 const char * const LL_CHANNEL = "Second Life Developer";

indra/llimage/llimage.cpp

 		mData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
 		if (!mData)
 		{
-			llwarns << "allocate image data: " << size << llendl;
+			llwarns << "Failed to allocate image data size [" << size << "]" << llendl;
 			size = 0 ;
 			mWidth = mHeight = 0 ;
 			mBadBufferAllocation = true ;

indra/llmessage/llcurl.cpp

 std::vector<LLMutex*> LLCurl::sSSLMutex;
 std::string LLCurl::sCAPath;
 std::string LLCurl::sCAFile;
-
-bool LLCurl::sMultiThreaded = false;
-static U32 sMainThreadID = 0;
+LLCurlThread* LLCurl::sCurlThread = NULL ;
 
 void check_curl_code(CURLcode code)
 {
 
 std::set<CURL*> LLCurl::Easy::sFreeHandles;
 std::set<CURL*> LLCurl::Easy::sActiveHandles;
-LLMutex* LLCurl::Easy::sHandleMutex = NULL;
-LLMutex* LLCurl::Easy::sMultiMutex = NULL;
 
 //static
 CURL* LLCurl::Easy::allocEasyHandle()
 {
 	CURL* ret = NULL;
-	LLMutexLock lock(sHandleMutex);
 	if (sFreeHandles.empty())
 	{
 		ret = curl_easy_init();
 		llerrs << "handle cannot be NULL!" << llendl;
 	}
 
-	LLMutexLock lock(sHandleMutex);
-	
 	if (sActiveHandles.find(handle) != sActiveHandles.end())
 	{
 		sActiveHandles.erase(handle);
 ////////////////////////////////////////////////////////////////////////////
 
 LLCurl::Multi::Multi()
-	: LLThread("Curl Multi"),
-	  mQueued(0),
+	: mQueued(0),
 	  mErrorCount(0),
-	  mPerformState(PERFORM_STATE_READY)
+	  mState(STATE_READY),
+	  mDead(FALSE),
+	  mMutexp(NULL),
+	  mDeletionMutexp(NULL)
 {
-	mQuitting = false;
-
-	mThreaded = LLCurl::sMultiThreaded && LLThread::currentID() == sMainThreadID;
-	if (mThreaded)
-	{
-		mSignal = new LLCondition(NULL);
-	}
-	else
-	{
-		mSignal = NULL;
-	}
-
 	mCurlMultiHandle = curl_multi_init();
 	if (!mCurlMultiHandle)
 	{
 		mCurlMultiHandle = curl_multi_init();
 	}
 	
-	llassert_always(mCurlMultiHandle);
+	llassert_always(mCurlMultiHandle);	
+
+	if(LLCurl::getCurlThread()->getThreaded())
+	{
+		mMutexp = new LLMutex(NULL) ;
+		mDeletionMutexp = new LLMutex(NULL) ;
+	}
+	LLCurl::getCurlThread()->addMulti(this) ;
+
 	++gCurlMultiCount;
 }
 
 LLCurl::Multi::~Multi()
 {
-	llassert(isStopped());
-
-	if (LLCurl::sMultiThreaded)
-	{
-		LLCurl::Easy::sMultiMutex->lock();
-	}
-
-	delete mSignal;
-	mSignal = NULL;
-
 	// Clean up active
 	for(easy_active_list_t::iterator iter = mEasyActiveList.begin();
 		iter != mEasyActiveList.end(); ++iter)
 	mEasyFreeList.clear();
 
 	check_curl_multi_code(curl_multi_cleanup(mCurlMultiHandle));
+
+	delete mMutexp ;
+	mMutexp = NULL ;
+	delete mDeletionMutexp ;
+	mDeletionMutexp = NULL ;
+
 	--gCurlMultiCount;
+}
 
-	if (LLCurl::sMultiThreaded)
+void LLCurl::Multi::lock()
+{
+	if(mMutexp)
 	{
-		LLCurl::Easy::sMultiMutex->unlock();
+		mMutexp->lock() ;
 	}
 }
 
+void LLCurl::Multi::unlock()
+{
+	if(mMutexp)
+	{
+		mMutexp->unlock() ;
+	}
+}
+
+void LLCurl::Multi::markDead()
+{
+	if(mDeletionMutexp)
+	{
+		mDeletionMutexp->lock() ;
+	}
+
+	mDead = TRUE ;
+
+	if(mDeletionMutexp)
+	{
+		mDeletionMutexp->unlock() ;
+	}
+}
+
+void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state)
+{
+	lock() ;
+	mState = state ;
+	if(mState == STATE_READY)
+	{
+		LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_NORMAL) ;
+	}
+	unlock() ;
+}
+
+LLCurl::Multi::ePerformState LLCurl::Multi::getState()
+{
+	ePerformState state ;
+
+	lock() ;
+	state = mState ;
+	unlock() ;
+
+	return state ;
+}
+	
+bool LLCurl::Multi::isCompleted() 
+{
+	return STATE_COMPLETED == getState() ;
+}
+
+bool LLCurl::Multi::waitToComplete()
+{
+	if(!mMutexp) //not threaded
+	{
+		doPerform() ;
+		return true ;
+	}
+
+	bool completed ;
+
+	lock() ;
+	completed = (STATE_COMPLETED == mState) ;
+	if(!completed)
+	{
+		LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ;
+	}
+	unlock() ;
+
+	return completed;
+}
+
 CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue)
 {
 	CURLMsg* curlmsg = curl_multi_info_read(mCurlMultiHandle, msgs_in_queue);
 	return curlmsg;
 }
 
-void LLCurl::Multi::perform()
+//return true if dead
+bool LLCurl::Multi::doPerform()
 {
-	if (mThreaded)
+	if(mDeletionMutexp)
 	{
-		if (mPerformState == PERFORM_STATE_READY)
+		mDeletionMutexp->lock() ;
+	}
+	bool dead = mDead ;
+
+	if(mDead)
+	{
+		setState(STATE_COMPLETED);
+		mQueued = 0 ;
+	}
+	else if(getState() != STATE_COMPLETED)
+	{		
+		setState(STATE_PERFORMING);
+
+		S32 q = 0;
+		for (S32 call_count = 0;
+				call_count < MULTI_PERFORM_CALL_REPEAT;
+				call_count++)
 		{
-			mSignal->signal();
+			CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q);
+			if (CURLM_CALL_MULTI_PERFORM != code || q == 0)
+			{
+				check_curl_multi_code(code);
+			
+				break;
+			}
 		}
+
+		mQueued = q;	
+		setState(STATE_COMPLETED) ;
 	}
-	else
+
+	if(mDeletionMutexp)
 	{
-		doPerform();
+		mDeletionMutexp->unlock() ;
 	}
-}
 
-void LLCurl::Multi::run()
-{
-	llassert(mThreaded);
-
-	while (!mQuitting)
-	{
-		mSignal->wait();
-		mPerformState = PERFORM_STATE_PERFORMING;
-		if (!mQuitting)
-		{
-			LLMutexLock lock(LLCurl::Easy::sMultiMutex);
-			doPerform();
-		}
-	}
-}
-
-void LLCurl::Multi::doPerform()
-{
-	S32 q = 0;
-	for (S32 call_count = 0;
-			call_count < MULTI_PERFORM_CALL_REPEAT;
-			call_count += 1)
-	{
-		CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q);
-		if (CURLM_CALL_MULTI_PERFORM != code || q == 0)
-		{
-			check_curl_multi_code(code);
-			break;
-		}
-	
-	}
-	mQueued = q;
-	mPerformState = PERFORM_STATE_COMPLETED;
+	return dead ;
 }
 
 S32 LLCurl::Multi::process()
 {
-	perform();
+	waitToComplete() ;
 
-	if (mPerformState != PERFORM_STATE_COMPLETED)
+	if (getState() != STATE_COMPLETED)
 	{
 		return 0;
 	}
 		}
 	}
 
-	mPerformState = PERFORM_STATE_READY;
+	setState(STATE_READY);
+
 	return processed;
 }
 
 	easyFree(easy);
 }
 
+//------------------------------------------------------------
+//LLCurlThread
+LLCurlThread::CurlRequest::CurlRequest(handle_t handle, LLCurl::Multi* multi, LLCurlThread* curl_thread) :
+	LLQueuedThread::QueuedRequest(handle, LLQueuedThread::PRIORITY_NORMAL, FLAG_AUTO_COMPLETE),
+	mMulti(multi),
+	mCurlThread(curl_thread)
+{	
+}
+
+LLCurlThread::CurlRequest::~CurlRequest()
+{	
+	if(mMulti)
+	{
+		mCurlThread->deleteMulti(mMulti) ;
+		mMulti = NULL ;
+	}
+}
+
+bool LLCurlThread::CurlRequest::processRequest()
+{
+	bool completed = true ;
+	if(mMulti)
+	{
+		completed = mCurlThread->doMultiPerform(mMulti) ;
+		setPriority(LLQueuedThread::PRIORITY_LOW) ;
+	}
+
+	return completed ;
+}
+
+void LLCurlThread::CurlRequest::finishRequest(bool completed)
+{
+	mCurlThread->deleteMulti(mMulti) ;
+	mMulti = NULL ;
+}
+	
+LLCurlThread::LLCurlThread(bool threaded) :
+	LLQueuedThread("curlthread", threaded)
+{
+}
+	
+//virtual 
+LLCurlThread::~LLCurlThread() 
+{
+}
+
+S32 LLCurlThread::update(U32 max_time_ms)
+{	
+	return LLQueuedThread::update(max_time_ms);
+}
+
+void LLCurlThread::addMulti(LLCurl::Multi* multi)
+{
+	multi->mHandle = generateHandle() ;
+
+	CurlRequest* req = new CurlRequest(multi->mHandle, multi, this) ;
+
+	if (!addRequest(req))
+	{
+		llwarns << "curl request added when the thread is quitted" << llendl;
+	}
+}
+	
+void LLCurlThread::killMulti(LLCurl::Multi* multi)
+{
+	multi->markDead() ;
+}
+
+//private
+bool LLCurlThread::doMultiPerform(LLCurl::Multi* multi) 
+{
+	return multi->doPerform() ;
+}
+
+//private
+void LLCurlThread::deleteMulti(LLCurl::Multi* multi) 
+{
+	delete multi ;
+}
+//------------------------------------------------------------
+
 //static
 std::string LLCurl::strerror(CURLcode errorcode)
 {
 	mActiveMulti(NULL),
 	mActiveRequestCount(0)
 {
-	mThreadID = LLThread::currentID();
 	mProcessing = FALSE;
 }
 
 LLCurlRequest::~LLCurlRequest()
 {
-	llassert_always(mThreadID == LLThread::currentID());
-
 	//stop all Multi handle background threads
 	for (curlmulti_set_t::iterator iter = mMultiSet.begin(); iter != mMultiSet.end(); ++iter)
 	{
-		LLCurl::Multi* multi = *iter;
-		multi->mQuitting = true;
-		if (multi->mThreaded)
-		{
-			while (!multi->isStopped())
-			{
-				multi->mSignal->signal();
-				apr_sleep(1000);
-			}
-		}
+		LLCurl::getCurlThread()->killMulti(*iter) ;
 	}
-	for_each(mMultiSet.begin(), mMultiSet.end(), DeletePointer());
+	mMultiSet.clear() ;
 }
 
 void LLCurlRequest::addMulti()
 {
-	llassert_always(mThreadID == LLThread::currentID());
 	LLCurl::Multi* multi = new LLCurl::Multi();
-	if (multi->mThreaded)
-	{
-		multi->start();
-	}
+	
 	mMultiSet.insert(multi);
 	mActiveMulti = multi;
 	mActiveRequestCount = 0;
 // Note: call once per frame
 S32 LLCurlRequest::process()
 {
-	llassert_always(mThreadID == LLThread::currentID());
 	S32 res = 0;
 
 	mProcessing = TRUE;
 		if (multi != mActiveMulti && tres == 0 && multi->mQueued == 0)
 		{
 			mMultiSet.erase(curiter);
-			multi->mQuitting = true;
-			if (multi->mThreaded)
-			{
-				while (!multi->isStopped())
-				{
-					multi->mSignal->signal();
-					apr_sleep(1000);
-				}
-			}
-
-			delete multi;
+			LLCurl::getCurlThread()->killMulti(multi);
 		}
 	}
 	mProcessing = FALSE;
 
 S32 LLCurlRequest::getQueued()
 {
-	llassert_always(mThreadID == LLThread::currentID());
 	S32 queued = 0;
 	for (curlmulti_set_t::iterator iter = mMultiSet.begin();
 		 iter != mMultiSet.end(); )
 		curlmulti_set_t::iterator curiter = iter++;
 		LLCurl::Multi* multi = *curiter;
 		queued += multi->mQueued;
-		if (multi->mPerformState != LLCurl::Multi::PERFORM_STATE_READY)
+		if (multi->getState() != LLCurl::Multi::STATE_READY)
 		{
 			++queued;
 		}
 	  mResultReturned(false)
 {
 	mMulti = new LLCurl::Multi();
-	if (mMulti->mThreaded)
-	{
-		mMulti->start();
-	}
+	
 	mEasy = mMulti->allocEasy();
 	if (mEasy)
 	{
 
 LLCurlEasyRequest::~LLCurlEasyRequest()
 {
-	mMulti->mQuitting = true;
-	if (mMulti->mThreaded)
-	{
-		while (!mMulti->isStopped())
-		{
-			mMulti->mSignal->signal();
-			apr_sleep(1000);
-		}
-	}
-	delete mMulti;
+	LLCurl::getCurlThread()->killMulti(mMulti) ;
 }
 	
 void LLCurlEasyRequest::setopt(CURLoption option, S32 value)
 	}
 }
 
-void LLCurlEasyRequest::perform()
-{
-	mMulti->perform();
-}
-
 // Usage: Call getRestult until it returns false (no more messages)
 bool LLCurlEasyRequest::getResult(CURLcode* result, LLCurl::TransferInfo* info)
 {
-	if (mMulti->mPerformState != LLCurl::Multi::PERFORM_STATE_COMPLETED)
+	if (!mMulti->isCompleted())
 	{ //we're busy, try again later
 		return false;
 	}
-	mMulti->mPerformState = LLCurl::Multi::PERFORM_STATE_READY;
+	mMulti->setState(LLCurl::Multi::STATE_READY) ;
 
 	if (!mEasy)
 	{
 
 void LLCurl::initClass(bool multi_threaded)
 {
-	sMainThreadID = LLThread::currentID();
-	sMultiThreaded = multi_threaded;
 	// 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
 
 	check_curl_code(code);
 	
-	Easy::sHandleMutex = new LLMutex(NULL);
-	Easy::sMultiMutex = new LLMutex(NULL);
-
 #if SAFE_SSL
 	S32 mutex_count = CRYPTO_num_locks();
 	for (S32 i=0; i<mutex_count; i++)
 	CRYPTO_set_id_callback(&LLCurl::ssl_thread_id);
 	CRYPTO_set_locking_callback(&LLCurl::ssl_locking_callback);
 #endif
+
+	sCurlThread = new LLCurlThread(multi_threaded) ;
 }
 
 void LLCurl::cleanupClass()
 {
+	//shut down curl thread
+	while(1)
+	{
+		if(!sCurlThread->update(1)) //finish all tasks
+		{
+			break ;
+		}
+	}
+	sCurlThread->shutdown() ;
+	delete sCurlThread ;
+	sCurlThread = NULL ;
+
 #if SAFE_SSL
 	CRYPTO_set_locking_callback(NULL);
 	for_each(sSSLMutex.begin(), sSSLMutex.end(), DeletePointer());
 #endif
 
-	delete Easy::sHandleMutex;
-	Easy::sHandleMutex = NULL;
-	delete Easy::sMultiMutex;
-	Easy::sMultiMutex = NULL;
-
 	for (std::set<CURL*>::iterator iter = Easy::sFreeHandles.begin(); iter != Easy::sFreeHandles.end(); ++iter)
 	{
 		CURL* curl = *iter;

indra/llmessage/llcurl.h

 #include "lliopipe.h"
 #include "llsd.h"
 #include "llthread.h"
+#include "llqueuedthread.h"
 
 class LLMutex;
+class LLCurlThread;
 
 // For whatever reason, this is not typedef'd in curl.h
 typedef size_t (*curl_header_callback)(void *ptr, size_t size, size_t nmemb, void *stream);
 	class Easy;
 	class Multi;
 
-	static bool sMultiThreaded;
-
 	struct TransferInfo
 	{
 		TransferInfo() : mSizeDownload(0.0), mTotalTime(0.0), mSpeedDownload(0.0) {}
 	static void ssl_locking_callback(int mode, int type, const char *file, int line);
 	static unsigned long ssl_thread_id(void);
 
+	static LLCurlThread* getCurlThread() { return sCurlThread ;}
 private:
 	static std::string sCAPath;
 	static std::string sCAFile;
 	static const unsigned int MAX_REDIRECTS;
+	static LLCurlThread* sCurlThread;
 };
 
 class LLCurl::Easy
 	U32 report(CURLcode);
 	void getTransferInfo(LLCurl::TransferInfo* info);
 
-	void prepRequest(const std::string& url, const std::vector<std::string>& headers, ResponderPtr, S32 time_out = 0, bool post = false);
+	void prepRequest(const std::string& url, const std::vector<std::string>& headers, LLCurl::ResponderPtr, S32 time_out = 0, bool post = false);
 
 	const char* getErrorBuffer();
 
 	// Note: char*'s not strings since we pass pointers to curl
 	std::vector<char*>	mStrings;
 
-	ResponderPtr		mResponder;
+	LLCurl::ResponderPtr		mResponder;
 
 	static std::set<CURL*> sFreeHandles;
 	static std::set<CURL*> sActiveHandles;
-	static LLMutex* sHandleMutex;
-	static LLMutex* sMultiMutex;
 };
 
-class LLCurl::Multi : public LLThread
+class LLCurl::Multi
 {
 	LOG_CLASS(Multi);
+
+	friend class LLCurlThread ;
+
+private:
+	~Multi();
+
+	void markDead() ;
+	bool doPerform();
+
 public:
 
 	typedef enum
 	{
-		PERFORM_STATE_READY=0,
-		PERFORM_STATE_PERFORMING=1,
-		PERFORM_STATE_COMPLETED=2
+		STATE_READY=0,
+		STATE_PERFORMING=1,
+		STATE_COMPLETED=2
 	} ePerformState;
 
-	Multi();
-	~Multi();
+	Multi();	
 
-	Easy* allocEasy();
-	bool addEasy(Easy* easy);
+	LLCurl::Easy* allocEasy();
+	bool addEasy(LLCurl::Easy* easy);	
+	void removeEasy(LLCurl::Easy* easy);
 	
-	void removeEasy(Easy* easy);
+	void lock() ;
+	void unlock() ;
+
+	void setState(ePerformState state) ;
+	ePerformState getState() ;
+	bool isCompleted() ;
+
+	bool waitToComplete() ;
 
 	S32 process();
-	void perform();
-	void doPerform();
 	
-	virtual void run();
-
 	CURLMsg* info_read(S32* msgs_in_queue);
 
 	S32 mQueued;
 	S32 mErrorCount;
 	
-	S32 mPerformState;
-
-	LLCondition* mSignal;
-	bool mQuitting;
-	bool mThreaded;
-
 private:
-	void easyFree(Easy*);
+	void easyFree(LLCurl::Easy*);
 	
 	CURLM* mCurlMultiHandle;
 
-	typedef std::set<Easy*> easy_active_list_t;
+	typedef std::set<LLCurl::Easy*> easy_active_list_t;
 	easy_active_list_t mEasyActiveList;
-	typedef std::map<CURL*, Easy*> easy_active_map_t;
+	typedef std::map<CURL*, LLCurl::Easy*> easy_active_map_t;
 	easy_active_map_t mEasyActiveMap;
-	typedef std::set<Easy*> easy_free_list_t;
+	typedef std::set<LLCurl::Easy*> easy_free_list_t;
 	easy_free_list_t mEasyFreeList;
+
+	LLQueuedThread::handle_t mHandle ;
+	ePerformState mState;
+
+	BOOL mDead ;
+	LLMutex* mMutexp ;
+	LLMutex* mDeletionMutexp ;
 };
 
+class LLCurlThread : public LLQueuedThread
+{
+public:
+
+	class CurlRequest : public LLQueuedThread::QueuedRequest
+	{
+	protected:
+		virtual ~CurlRequest(); // use deleteRequest()
+		
+	public:
+		CurlRequest(handle_t handle, LLCurl::Multi* multi, LLCurlThread* curl_thread);
+
+		/*virtual*/ bool processRequest();
+		/*virtual*/ void finishRequest(bool completed);
+
+	private:
+		// input
+		LLCurl::Multi* mMulti;
+		LLCurlThread*  mCurlThread;
+	};
+	friend class CurlRequest;
+
+public:
+	LLCurlThread(bool threaded = true) ;
+	virtual ~LLCurlThread() ;
+
+	S32 update(U32 max_time_ms);
+
+	void addMulti(LLCurl::Multi* multi) ;
+	void killMulti(LLCurl::Multi* multi) ;
+
+private:
+	bool doMultiPerform(LLCurl::Multi* multi) ;
+	void deleteMulti(LLCurl::Multi* multi) ;
+} ;
+
 namespace boost
 {
 	void intrusive_ptr_add_ref(LLCurl::Responder* p);
 	LLCurl::Multi* mActiveMulti;
 	S32 mActiveRequestCount;
 	BOOL mProcessing;
-	U32 mThreadID; // debug
 };
 
 class LLCurlEasyRequest
 	void slist_append(const char* str);
 	void sendRequest(const std::string& url);
 	void requestComplete();
-	void perform();
 	bool getResult(CURLcode* result, LLCurl::TransferInfo* info = NULL);
 	std::string getErrorString();
+	bool isCompleted() {return mMulti->isCompleted() ;}
+	bool wait() { return mMulti->waitToComplete(); }
 
 	LLCurl::Easy* getEasy() const { return mEasy; }
 

indra/llmessage/llurlrequest.cpp

 {
 	LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
 	delete mDetail;
+	mDetail = NULL ;
 }
 
 void LLURLRequest::setURL(const std::string& url)
 		static LLFastTimer::DeclareTimer FTM_URL_PERFORM("Perform");
 		{
 			LLFastTimer t(FTM_URL_PERFORM);
-			mDetail->mCurlRequest->perform();
+			if(!mDetail->mCurlRequest->wait())
+			{
+				return status ;
+			}
 		}
 
 		while(1)

indra/llprimitive/llvolumexml.cpp

 
 //============================================================================
 
-LLXMLNode *LLVolumeXml::exportProfileParams(const LLProfileParams* params)
+LLPointer<LLXMLNode> LLVolumeXml::exportProfileParams(const LLProfileParams* params)
 {
-	LLXMLNode *ret = new LLXMLNode("profile", FALSE);
+	LLPointer<LLXMLNode> ret = new LLXMLNode("profile", FALSE);
 
 	ret->createChild("curve_type", TRUE)->setByteValue(1, &params->getCurveType());
 	ret->createChild("interval", FALSE)->setFloatValue(2, &params->getBegin());
 }
 
 
-LLXMLNode *LLVolumeXml::exportPathParams(const LLPathParams* params)
+LLPointer<LLXMLNode> LLVolumeXml::exportPathParams(const LLPathParams* params)
 {
-	LLXMLNode *ret = new LLXMLNode("path", FALSE); 
+	LLPointer<LLXMLNode> ret = new LLXMLNode("path", FALSE); 
 	ret->createChild("curve_type", TRUE)->setByteValue(1, &params->getCurveType());
 	ret->createChild("interval", FALSE)->setFloatValue(2, &params->getBegin());
 	ret->createChild("scale", FALSE)->setFloatValue(2, params->getScale().mV);
 }
 
 
-LLXMLNode *LLVolumeXml::exportVolumeParams(const LLVolumeParams* params)
+LLPointer<LLXMLNode> LLVolumeXml::exportVolumeParams(const LLVolumeParams* params)
 {
-	LLXMLNode *ret = new LLXMLNode("shape", FALSE);
+	LLPointer<LLXMLNode> ret = new LLXMLNode("shape", FALSE);
 	
-	exportPathParams(&params->getPathParams())->setParent(ret);
-	exportProfileParams(&params->getProfileParams())->setParent(ret);
+	LLPointer<LLXMLNode> node ;
+	node = exportPathParams(&params->getPathParams()) ;
+	node->setParent(ret);
+	node = exportProfileParams(&params->getProfileParams()) ;
+	node->setParent(ret);
 
 	return ret;
 }

indra/llprimitive/llvolumexml.h

 class LLVolumeXml
 {
 public:
-	static LLXMLNode* exportProfileParams(const LLProfileParams* params);
+	static LLPointer<LLXMLNode> exportProfileParams(const LLProfileParams* params);
 
-	static LLXMLNode* exportPathParams(const LLPathParams* params);
+	static LLPointer<LLXMLNode> exportPathParams(const LLPathParams* params);
 
-	static LLXMLNode* exportVolumeParams(const LLVolumeParams* params);
+	static LLPointer<LLXMLNode> exportVolumeParams(const LLVolumeParams* params);
 };
 
 #endif // LL_LLVOLUMEXML_H

indra/llui/llui.cpp

 	LLXMLNodePtr root;
 	BOOL success  = LLXMLNode::parseFile(filename, root, NULL);
 	Paths paths;
-	LLXUIParser parser;
-	parser.readXUI(root, paths, filename);
 
+	if(success)
+	{
+		LLXUIParser parser;
+		parser.readXUI(root, paths, filename);
+	}
 	sXUIPaths.clear();
 	
 	if (success && paths.validateBlock())

indra/llxml/llxmlnode.cpp

 	LLFILE* fp = LLFile::fopen(filename, "rb");		/* Flawfinder: ignore */
 	if (fp == NULL)
 	{
-		node = new LLXMLNode();
+		node = NULL ;
 		return false;
 	}
 	fseek(fp, 0, SEEK_END);
 	{
 		llwarns << "Parse failure - wrong number of top-level nodes xml."
 				<< llendl;
-		node = new LLXMLNode();
+		node = NULL ;
 		return false;
 	}
 
 	{
 		llwarns << "Parse failure - wrong number of top-level nodes xml."
 				<< llendl;
-		node = new LLXMLNode();
+		node = NULL;
 		return false;
 	}
 
 	{
 		return mDefault->getChild(name, node, FALSE);
 	}
-	node = new LLXMLNode();
+	node = NULL;
 	return false;
 }
 
 	{
 		return mDefault->getAttribute(name, node, FALSE);
 	}
-	node = new LLXMLNode();
+	
 	return false;
 }
 

indra/llxuixml/llxuiparser.cpp

 	if( !file.isOpen() )
 	{
 		LL_WARNS("ReadXUI") << "Unable to open file " << filename << LL_ENDL;
+		XML_ParserFree( mParser );
 		return false;
 	}
 

indra/newview/featuretable_mac.txt

 RenderTransparentWater			1	1
 RenderTreeLODFactor				1	1.0
 RenderUseImpostors				1	1
-RenderVBOEnable					1	0
+RenderVBOEnable					1	1
 RenderVBOMappingDisable			1	1
 RenderVolumeLODFactor			1	2.0
 UseStartScreen					1	1

indra/newview/llappviewer.cpp

 					}
 				}
 				gMeshRepo.update() ;
+				
+				if(!LLCurl::getCurlThread()->update(1))
+				{
+					LLCurl::getCurlThread()->pause() ; //nothing in the curl thread.
+				}
 
 				if(!total_work_pending) //pause texture fetching threads if nothing to process.
 				{
 		pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
 		pending += LLVFSThread::updateClass(0);
 		pending += LLLFSThread::updateClass(0);
+		pending += LLCurl::getCurlThread()->update(1) ;
 		F64 idle_time = idleTimer.getElapsedTimeF64();
 		if(!pending)
 		{
 			break;
 		}
 	}
+	LLCurl::getCurlThread()->pause() ;
 
 	// Delete workers first
 	// shotdown all worker threads before deleting them in case of co-dependencies

indra/newview/lldebugview.cpp

 	gTextureCategoryView = NULL;
 }
 
-BOOL LLDebugView::postBuild()
-{
-	mFloaterSnapRegion = getRootView()->getChildView("floater_snap_region");
-	
-	return TRUE;
-}
-
 void LLDebugView::init()
 {
 	LLRect r;
 
 void LLDebugView::draw()
 {
+	if (mFloaterSnapRegion == NULL)
+	{
+		mFloaterSnapRegion = getRootView()->getChildView("floater_snap_region");
+	}
+
 	LLRect debug_rect;
 	mFloaterSnapRegion->localRectToOtherView(mFloaterSnapRegion->getLocalRect(), &debug_rect, getParent());
 

indra/newview/lldebugview.h

 	LLDebugView(const Params&);
 	~LLDebugView();
 
-	BOOL postBuild();
-	
 	void init();
 	void draw();
 	

indra/newview/llfloatermodelpreview.cpp

 //static
 void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata)
 {
-	S32 num_modes = 4;
-	S32 which_mode = 3;
-	static S32 previous_mode = which_mode;
+	S32 num_lods = 4;
+	S32 which_mode;
 
 	LLCtrlSelectionInterface* iface = sInstance->childGetSelectionInterface("physics_lod_combo");
 	if (iface)
 	{
 		which_mode = iface->getFirstSelectedIndex();
 	}
+	else
+	{
+		llwarns << "no iface" << llendl;
+		return;
+	}
+
+	if (which_mode <= 0)
+	{
+		llwarns << "which_mode out of range, " << which_mode << llendl;
+	}
 
 	S32 file_mode = iface->getItemCount() - 1;
-	bool file_browse = which_mode == file_mode;
-	bool lod_to_file = file_browse && (previous_mode != file_mode);
-	bool file_to_lod = !file_browse && (previous_mode == file_mode);
-
-	if (!lod_to_file)
-	{
-		which_mode = num_modes - which_mode;
-		sInstance->mModelPreview->setPhysicsFromLOD(which_mode);
-	}
-
-	if (lod_to_file || file_to_lod)
-	{
-		LLModelPreview *model_preview = sInstance->mModelPreview;
-		if (model_preview)
-		{
-			model_preview->refresh();
-			model_preview->updateStatusMessages();
-		}
-	}
-
-	previous_mode = which_mode;
+	if (which_mode < file_mode)
+	{
+		S32 which_lod = num_lods - which_mode;
+		sInstance->mModelPreview->setPhysicsFromLOD(which_lod);
+	}
+
+	LLModelPreview *model_preview = sInstance->mModelPreview;
+	if (model_preview)
+	{
+		model_preview->refresh();
+		model_preview->updateStatusMessages();
+	}
 }
 
 //static 

indra/newview/llviewermessage.cpp

 	gCacheName->setUpstream(sim);
 */
 
+	// Make sure we're standing
+	gAgent.standUp();
+
 	// now, use the circuit info to tell simulator about us!
 	LL_INFOS("Messaging") << "process_teleport_finish() Enabling "
 			<< sim_host << " with code " << msg->mOurCircuitCode << LL_ENDL;

indra/newview/llviewertexture.cpp

 		}
 	}
 	mPauseLoadedCallBacks = FALSE ;
+	mLastCallBackActiveTime = sCurrentTime ;
 	if(need_raw)
 	{
 		mSaveRawImage = TRUE ;
 {
 	static const F32 MAX_INACTIVE_TIME = 120.f ; //seconds
 
+	if(mPauseLoadedCallBacks)
+	{
+		destroyRawImage();
+		return false; //paused
+	}
 	if (mNeedsCreateTexture)
 	{
 		return false;
 
 		// Remove ourself from the global list of textures with callbacks
 		gTextureList.mCallbackList.erase(this);
-	}
-	if(mPauseLoadedCallBacks)
-	{
-		destroyRawImage();
-		return res; //paused
-	}
+	}	
 
 	S32 gl_discard = getDiscardLevel();
 
 
 void LLViewerFetchedTexture::destroyRawImage()
 {	
-	if (mAuxRawImage.notNull()) sAuxCount--;
+	if (mAuxRawImage.notNull())
+	{
+		sAuxCount--;
+		mAuxRawImage = NULL;
+	}
 
 	if (mRawImage.notNull()) 
 	{
 			}		
 			setCachedRawImage() ;
 		}
+		
+		mRawImage = NULL;
+	
+		mIsRawImageValid = FALSE;
+		mRawDiscardLevel = INVALID_DISCARD_LEVEL;
 	}
-
-	mRawImage = NULL;
-	mAuxRawImage = NULL;
-	mIsRawImageValid = FALSE;
-	mRawDiscardLevel = INVALID_DISCARD_LEVEL;
 }
 
 //use the mCachedRawImage to (re)generate the gl texture.

indra/newview/llvoicevivox.cpp

 
 LLVivoxProtocolParser::LLVivoxProtocolParser()
 {
-	parser = NULL;
 	parser = XML_ParserCreate(NULL);
 	
 	reset();

indra/newview/llworld.cpp

 	max_x = (S32)region_x + range;
 	max_y = (S32)region_y + range;
 
-	F32 height = 0.f;
-	
 	for (region_list_t::iterator iter = mRegionList.begin();
 		 iter != mRegionList.end(); ++iter)
 	{
 		LLViewerRegion* regionp = *iter;
 		LLVOWater* waterp = regionp->getLand().getWaterObj();
-		height += regionp->getWaterHeight();
 		if (waterp)
 		{
 			gObjectList.updateActive(waterp);
 
 	// Now, get a list of the holes
 	S32 x, y;
+	F32 water_height = gAgent.getRegion()->getWaterHeight() + 256.f;
 	for (x = min_x; x <= max_x; x += rwidth)
 	{
 		for (y = min_y; y <= max_y; y += rwidth)
 				waterp->setUseTexture(FALSE);
 				waterp->setPositionGlobal(LLVector3d(x + rwidth/2,
 													 y + rwidth/2,
-													 256.f+DEFAULT_WATER_HEIGHT));
+													 water_height));
 				waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, 512.f));
 				gPipeline.createObject(waterp);
 				mHoleWaterObjects.push_back(waterp);
 		}
 
 		waterp->setRegion(gAgent.getRegion());
-		LLVector3d water_pos(water_center_x, water_center_y, 
-			DEFAULT_WATER_HEIGHT+256.f);
+		LLVector3d water_pos(water_center_x, water_center_y, water_height) ;
 		LLVector3 water_scale((F32) dim[0], (F32) dim[1], 512.f);
 
 		//stretch out to horizon

indra/newview/llxmlrpctransaction.cpp

 			// continue onward
 		}
 	}
-	
-	//const F32 MAX_PROCESSING_TIME = 0.05f;
-	//LLTimer timer;
-
-	mCurlRequest->perform();
-
-	/*while (mCurlRequest->perform() > 0)
+		
+	if(!mCurlRequest->wait())
 	{
-		if (timer.getElapsedTimeF32() >= MAX_PROCESSING_TIME)
-		{
-			return false;
-		}
-	}*/
+		return false ;
+	}
 
 	while(1)
 	{

indra/newview/skins/default/xui/da/floater_buy_currency.xml

 		L$ [AMT]
 	</text>
 	<text name="currency_links">
-		[http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency] | [http://www.secondlife.com/my/account/exchange_rates.php exchange rate]
+		[http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency]
 	</text>
 	<text name="exchange_rate_note">
 		Indtast beløbet for at se nyeste valutakurs.

indra/newview/skins/default/xui/de/floater_buy_currency.xml

 		[AMT] L$
 	</text>
 	<text name="currency_links">
-		[http://www.secondlife.com/my/account/payment_method_management.php?lang=de-DE Zahlungsart] | [http://www.secondlife.com/my/account/currency.php?lang=de-DE Währung] | [http://www.secondlife.com/my/account/exchange_rates.php?lang=de-DE Umtauschrate]
+		[http://www.secondlife.com/my/account/payment_method_management.php?lang=de-DE Zahlungsart] | [http://www.secondlife.com/my/account/currency.php?lang=de-DE Währung]
 	</text>
 	<text name="exchange_rate_note">
 		Geben Sie den Betrag erneut ein, um die aktuellste Umtauschrate anzuzeigen.

indra/newview/skins/default/xui/en/floater_buy_currency.xml

      width="300"
      height="30"
      name="currency_links">
-      [http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency] | [http://www.secondlife.com/my/account/exchange_rates.php exchange rate]
+      [http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency]
     </text>
     <text
      type="string"

indra/newview/skins/default/xui/en/floater_snapshot.xml

  name="Snapshot"
  help_topic="snapshot"
  save_rect="true"
- save_visibility="true"
+ save_visibility="false"
  title="SNAPSHOT PREVIEW"
  width="470">
     <floater.string

indra/newview/skins/default/xui/es/floater_buy_currency.xml

 		[AMT] L$
 	</text>
 	<text name="currency_links">
-		[http://www.secondlife.com/my/account/payment_method_management.php método de pago] | [http://www.secondlife.com/my/account/currency.php moneda] | [http://www.secondlife.com/my/account/exchange_rates.php tipo de cambio]
+		[http://www.secondlife.com/my/account/payment_method_management.php método de pago] | [http://www.secondlife.com/my/account/currency.php moneda]
 	</text>
 	<text name="exchange_rate_note">
 		Vuelve a escribir la cantidad para ver el tipo de cambio más reciente.

indra/newview/skins/default/xui/fr/floater_buy_currency.xml

 		[AMT] L$
 	</text>
 	<text name="currency_links">
-		[http://www.secondlife.com/my/account/payment_method_management.php?lang=fr-FR mode de paiement] | [http://www.secondlife.com/my/account/currency.php?lang=fr-FR devise] | [http://www.secondlife.com/my/account/exchange_rates.php?lang=fr-FR taux de change]
+		[http://www.secondlife.com/my/account/payment_method_management.php?lang=fr-FR mode de paiement] | [http://www.secondlife.com/my/account/currency.php?lang=fr-FR devise]
 	</text>
 	<text name="exchange_rate_note">
 		Saisissez à nouveau le montant pour voir le taux de change actuel.

indra/newview/skins/default/xui/fr/floater_snapshot.xml

 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Snapshot" title="APERÇU DE LA PHOTO" width="247">
+<floater name="Snapshot" title="APERÇU DE LA PHOTO">
 	<floater.string name="unknown">
 		inconnu
 	</floater.string>

indra/newview/skins/default/xui/it/floater_buy_currency.xml

 		[AMT]L$
 	</text>
 	<text name="currency_links">
-		[http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency] | [http://www.secondlife.com/my/account/exchange_rates.php exchange rate]
+		[http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency]
 	</text>
 	<text name="exchange_rate_note">
 		Riscrivi l&apos;importo per vedere l&apos;ultimo tasso al cambio.

indra/newview/skins/default/xui/it/floater_snapshot.xml

 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Snapshot" title="ANTEPRIMA FOTOGRAFIA" width="247">
+<floater name="Snapshot" title="ANTEPRIMA FOTOGRAFIA">
 	<floater.string name="unknown">
 		sconosciuto
 	</floater.string>

indra/newview/skins/default/xui/ja/floater_buy_currency.xml

 		L$ [AMT]
 	</text>
 	<text name="currency_links">
-		[http://www.secondlife.com/my/account/payment_method_management.php?lang=ja-JP 支払方法] | [http://www.secondlife.com/my/account/currency.php?lang=ja-JP 通貨] | [http://www.secondlife.com/my/account/exchange_rates.php?lang=ja-JP 換算レート]
+		[http://www.secondlife.com/my/account/payment_method_management.php?lang=ja-JP 支払方法] | [http://www.secondlife.com/my/account/currency.php?lang=ja-JP 通貨]
 	</text>
 	<text name="exchange_rate_note">
 		金額を再入力して最新換算レートを確認します。

indra/newview/skins/default/xui/pl/floater_buy_currency.xml

 		[AMT]L$
 	</text>
 	<text name="currency_links">
-		[http://www.secondlife.com/my/account/payment_method_management.php metoda płatności] | [http://www.secondlife.com/my/account/currency.php waluta] | [http://www.secondlife.com/my/account/exchange_rates.php kurs wymiany]
+		[http://www.secondlife.com/my/account/payment_method_management.php metoda płatności] | [http://www.secondlife.com/my/account/currency.php waluta]
 	</text>
 	<text name="exchange_rate_note">
 		Wpisz ponownie kwotę aby zobaczyć ostatni kurs wymiany.

indra/newview/skins/default/xui/pt/floater_buy_currency.xml

 		L$ [AMT]
 	</text>
 	<text name="currency_links">
-		[http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency] | [http://www.secondlife.com/my/account/exchange_rates.php exchange rate]
+		[http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency]
 	</text>
 	<text name="exchange_rate_note">
 		Digite o valor novamente para ver o câmbio atual.

indra/newview/skins/default/xui/ru/floater_buy_currency.xml

 		L$ [AMT]
 	</text>
 	<text name="currency_links">
-		[http://www.secondlife.com/my/account/payment_method_management.php способ оплаты] | [http://www.secondlife.com/my/account/currency.php валюта] | [http://www.secondlife.com/my/account/exchange_rates.php обменный курс]
+		[http://www.secondlife.com/my/account/payment_method_management.php способ оплаты] | [http://www.secondlife.com/my/account/currency.php валюта]
 	</text>
 	<text name="exchange_rate_note">
 		Повторно введите сумму, чтобы увидеть новый обменный курс.

indra/newview/skins/default/xui/tr/floater_buy_currency.xml

 		L$ [AMT]
 	</text>
 	<text name="currency_links">
-		[http://www.secondlife.com/my/account/payment_method_management.php ödeme yöntemi] | [http://www.secondlife.com/my/account/currency.php para birimi | [http://www.secondlife.com/my/account/exchange_rates.php döviz kurları]
+		[http://www.secondlife.com/my/account/payment_method_management.php ödeme yöntemi] | [http://www.secondlife.com/my/account/currency.php para birimi
 	</text>
 	<text name="exchange_rate_note">
 		En son döviz kurunu görmek için miktarı yeniden girin.

indra/newview/skins/default/xui/zh/floater_buy_currency.xml

 		L$ [AMT]
 	</text>
 	<text name="currency_links">
-		[http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency] | [http://www.secondlife.com/my/account/exchange_rates.php exchange rate]
+		[http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency]
 	</text>
 	<text name="exchange_rate_note">
 		Re-enter amount to see the latest exchange rate.