From b0d4919fd453fea9afc1cc0745140e83992997b6 Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Thu, 4 Mar 2010 15:02:30 -0700
Subject: fix for EXT-5683: viewer crashes at llcommon/llworkerthread.cpp(323):
 ERROR: LLWorkerClass::checkWork: ASSERT(workreq).

---
 indra/llcommon/llworkerthread.cpp | 36 +++++++++++++++++++++++++++++++++++-
 indra/llcommon/llworkerthread.h   |  3 +++
 2 files changed, 38 insertions(+), 1 deletion(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp
index 1b0e03cb2a..411977474b 100644
--- a/indra/llcommon/llworkerthread.cpp
+++ b/indra/llcommon/llworkerthread.cpp
@@ -65,6 +65,27 @@ LLWorkerThread::~LLWorkerThread()
 	// ~LLQueuedThread() will be called here
 }
 
+//called only in destructor.
+void LLWorkerThread::clearDeleteList()
+{
+	// Delete any workers in the delete queue (should be safe - had better be!)
+	if (!mDeleteList.empty())
+	{
+		llwarns << "Worker Thread: " << mName << " destroyed with " << mDeleteList.size()
+				<< " entries in delete list." << llendl;
+
+		mDeleteMutex->lock();
+		for (delete_list_t::iterator iter = mDeleteList.begin(); iter != mDeleteList.end(); ++iter)
+		{
+			(*iter)->mRequestHandle = LLWorkerThread::nullHandle();
+			(*iter)->clearFlags(LLWorkerClass::WCF_HAVE_WORK);
+			delete *iter ;
+		}
+		mDeleteList.clear() ;
+		mDeleteMutex->unlock() ;
+	}
+}
+
 // virtual
 S32 LLWorkerThread::update(U32 max_time_ms)
 {
@@ -320,7 +341,20 @@ bool LLWorkerClass::checkWork(bool aborting)
 	if (mRequestHandle != LLWorkerThread::nullHandle())
 	{
 		LLWorkerThread::WorkRequest* workreq = (LLWorkerThread::WorkRequest*)mWorkerThread->getRequest(mRequestHandle);
-		llassert_always(workreq);
+		if(!workreq)
+		{
+			if(mWorkerThread->isQuitting() || mWorkerThread->isStopped()) //the mWorkerThread is not running
+			{
+				mRequestHandle = LLWorkerThread::nullHandle();
+				clearFlags(WCF_HAVE_WORK);
+				return true ;
+			}
+			else
+			{
+				llassert_always(workreq);
+			}
+		}
+
 		LLQueuedThread::status_t status = workreq->getStatus();
 		if (status == LLWorkerThread::STATUS_ABORTED)
 		{
diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h
index a1e85d2ecc..1756ebab6b 100644
--- a/indra/llcommon/llworkerthread.h
+++ b/indra/llcommon/llworkerthread.h
@@ -80,6 +80,9 @@ public:
 		S32 mParam;
 	};
 
+protected:
+	void clearDeleteList() ;
+
 private:
 	typedef std::list<LLWorkerClass*> delete_list_t;
 	delete_list_t mDeleteList;
-- 
cgit v1.2.3