aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra')
-rw-r--r--linden/indra/llcommon/llthread.cpp35
-rw-r--r--linden/indra/llcommon/llthread.h8
-rw-r--r--linden/indra/newview/lltexturefetch.cpp42
3 files changed, 20 insertions, 65 deletions
diff --git a/linden/indra/llcommon/llthread.cpp b/linden/indra/llcommon/llthread.cpp
index 60ccd5c..692d6c4 100644
--- a/linden/indra/llcommon/llthread.cpp
+++ b/linden/indra/llcommon/llthread.cpp
@@ -283,7 +283,6 @@ LLMutex::LLMutex(apr_pool_t *poolp) :
283 apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp); 283 apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp);
284} 284}
285 285
286
287LLMutex::~LLMutex() 286LLMutex::~LLMutex()
288{ 287{
289#if _DEBUG 288#if _DEBUG
@@ -297,40 +296,14 @@ LLMutex::~LLMutex()
297 } 296 }
298} 297}
299 298
300
301void LLMutex::lock()
302{
303 apr_thread_mutex_lock(mAPRMutexp);
304}
305
306void LLMutex::unlock()
307{
308 apr_thread_mutex_unlock(mAPRMutexp);
309}
310
311bool LLMutex::isLocked() 299bool LLMutex::isLocked()
312{ 300{
313 apr_status_t status = apr_thread_mutex_trylock(mAPRMutexp); 301 if (!tryLock())
314 if (APR_STATUS_IS_EBUSY(status))
315 { 302 {
316 return true; 303 return true;
317 } 304 }
318 else 305 apr_thread_mutex_unlock(mAPRMutexp);
319 { 306 return false;
320 apr_thread_mutex_unlock(mAPRMutexp);
321 return false;
322 }
323}
324
325//trys to grab a lock and if sucessful returns true
326bool LLMutex::tryLock()
327{
328 apr_status_t status = apr_thread_mutex_trylock(mAPRMutexp);
329 if (APR_STATUS_IS_EBUSY(status))
330 {
331 return false;
332 }
333 return true;
334} 307}
335 308
336//============================================================================ 309//============================================================================
@@ -343,14 +316,12 @@ LLCondition::LLCondition(apr_pool_t *poolp) :
343 apr_thread_cond_create(&mAPRCondp, mAPRPoolp); 316 apr_thread_cond_create(&mAPRCondp, mAPRPoolp);
344} 317}
345 318
346
347LLCondition::~LLCondition() 319LLCondition::~LLCondition()
348{ 320{
349 apr_thread_cond_destroy(mAPRCondp); 321 apr_thread_cond_destroy(mAPRCondp);
350 mAPRCondp = NULL; 322 mAPRCondp = NULL;
351} 323}
352 324
353
354void LLCondition::wait() 325void LLCondition::wait()
355{ 326{
356 apr_thread_cond_wait(mAPRCondp, mAPRMutexp); 327 apr_thread_cond_wait(mAPRCondp, mAPRMutexp);
diff --git a/linden/indra/llcommon/llthread.h b/linden/indra/llcommon/llthread.h
index d773fa4..ed76a3b 100644
--- a/linden/indra/llcommon/llthread.h
+++ b/linden/indra/llcommon/llthread.h
@@ -131,10 +131,12 @@ public:
131 LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex 131 LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex
132 ~LLMutex(); 132 ~LLMutex();
133 133
134 void lock(); // blocks 134 void lock() { apr_thread_mutex_lock(mAPRMutexp); }
135 void unlock(); 135 void unlock() { apr_thread_mutex_unlock(mAPRMutexp); }
136 // Returns true if lock was obtained successfully.
137 bool tryLock() { return !APR_STATUS_IS_EBUSY(apr_thread_mutex_trylock(mAPRMutexp)); }
138
136 bool isLocked(); // non-blocking, but does do a lock/unlock so not free 139 bool isLocked(); // non-blocking, but does do a lock/unlock so not free
137 bool tryLock(); //non-blocking, but not free, returns true if grabed lock
138 140
139protected: 141protected:
140 apr_thread_mutex_t *mAPRMutexp; 142 apr_thread_mutex_t *mAPRMutexp;
diff --git a/linden/indra/newview/lltexturefetch.cpp b/linden/indra/newview/lltexturefetch.cpp
index 3a5665c..62b4c8b 100644
--- a/linden/indra/newview/lltexturefetch.cpp
+++ b/linden/indra/newview/lltexturefetch.cpp
@@ -744,26 +744,17 @@ bool LLTextureFetchWorker::doWork(S32 param)
744 } 744 }
745 else if (mSentRequest == UNSENT) 745 else if (mSentRequest == UNSENT)
746 { 746 {
747 if(mFetcher->mQueueMutex.tryLock()) 747 // Add this to the network queue and sit here.
748 { 748 // LLTextureFetch::update() will send off a request which will change our state
749 // Add this to the network queue and sit here. 749 mRequestedSize = mDesiredSize;
750 // LLTextureFetch::update() will send off a request which will change our state 750 mRequestedDiscard = mDesiredDiscard;
751 mRequestedSize = mDesiredSize; 751 mSentRequest = QUEUED;
752 mRequestedDiscard = mDesiredDiscard; 752 mFetcher->addToNetworkQueue(this);
753 mSentRequest = QUEUED; 753 setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
754 mFetcher->addToNetworkQueue(this);
755 setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
756 mFetcher->mQueueMutex.unlock();
757 }
758 return false; 754 return false;
759 } 755 }
760 else 756 else
761 { 757 {
762 // Shouldn't need to do anything here
763 //llassert_always(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end());
764 // Make certain this is in the network queue
765 //mFetcher->addToNetworkQueue(this);
766 //setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
767 return false; 758 return false;
768 } 759 }
769 } 760 }
@@ -1473,23 +1464,12 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)
1473 } 1464 }
1474} 1465}
1475 1466
1476// Need to hold mQueueMutex when entering this function SNOW-196
1477// Snowglobe ToDo fix holding mQueueMutex over the entire function, we only need
1478// it for the mRequestMap access
1479// protected 1467// protected
1480void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker) 1468void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker)
1481{ 1469{
1482 bool is_worker_in_request_map = (mRequestMap.find(worker->mID) != mRequestMap.end());
1483
1484 LLMutexLock lock(&mNetworkQueueMutex); 1470 LLMutexLock lock(&mNetworkQueueMutex);
1485 if (is_worker_in_request_map) 1471 mNetworkQueue.insert(worker->mID);
1486 { 1472 for (cancel_queue_t::iterator iter1 = mCancelQueue.begin(); iter1 != mCancelQueue.end(); ++iter1)
1487 // only add to the queue if in the request map
1488 // i.e. a delete has not been requested
1489 mNetworkQueue.insert(worker->mID);
1490 }
1491 for (cancel_queue_t::iterator iter1 = mCancelQueue.begin();
1492 iter1 != mCancelQueue.end(); ++iter1)
1493 { 1473 {
1494 iter1->second.erase(worker->mID); 1474 iter1->second.erase(worker->mID);
1495 } 1475 }
@@ -1715,8 +1695,10 @@ void LLTextureFetch::sendRequestListToSimulators()
1715 LLTextureFetchWorker* req = getWorker(*curiter); 1695 LLTextureFetchWorker* req = getWorker(*curiter);
1716 if (!req) 1696 if (!req)
1717 { 1697 {
1698 // This happens when a request was removed from mRequestMap in a race
1699 // with adding it to mNetworkQueue by doWork (see SNOW-196).
1718 mNetworkQueue.erase(curiter); 1700 mNetworkQueue.erase(curiter);
1719 continue; // paranoia 1701 continue;
1720 } 1702 }
1721 llassert(req->mState == LLTextureFetchWorker::LOAD_FROM_NETWORK || LLTextureFetchWorker::LOAD_FROM_SIMULATOR); 1703 llassert(req->mState == LLTextureFetchWorker::LOAD_FROM_NETWORK || LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
1722 if ((req->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK) && 1704 if ((req->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK) &&