From 78233d1bf9930575ee7250257ac68603f41f568a Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 5 Dec 2011 17:55:40 -0600 Subject: SH-2652 WIP -- Add timers to relevant areas, pause render pipeline while occlusion queries from previous frame are still pending and perform texture decode work. --- indra/llcommon/llqueuedthread.cpp | 4 ++-- indra/llcommon/llqueuedthread.h | 4 ++-- indra/llcommon/llworkerthread.cpp | 2 +- indra/llcommon/llworkerthread.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 5dee7a3541..1738c16dea 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -109,7 +109,7 @@ void LLQueuedThread::shutdown() // MAIN THREAD // virtual -S32 LLQueuedThread::update(U32 max_time_ms) +S32 LLQueuedThread::update(F32 max_time_ms) { if (!mStarted) { @@ -122,7 +122,7 @@ S32 LLQueuedThread::update(U32 max_time_ms) return updateQueue(max_time_ms); } -S32 LLQueuedThread::updateQueue(U32 max_time_ms) +S32 LLQueuedThread::updateQueue(F32 max_time_ms) { F64 max_time = (F64)max_time_ms * .001; LLTimer timer; diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h index 499d13a792..d3704b0fe2 100644 --- a/indra/llcommon/llqueuedthread.h +++ b/indra/llcommon/llqueuedthread.h @@ -173,8 +173,8 @@ protected: public: bool waitForResult(handle_t handle, bool auto_complete = true); - virtual S32 update(U32 max_time_ms); - S32 updateQueue(U32 max_time_ms); + virtual S32 update(F32 max_time_ms); + S32 updateQueue(F32 max_time_ms); void waitOnPending(); void printQueueStats(); diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp index 4988bdf570..3d05a30ac2 100644 --- a/indra/llcommon/llworkerthread.cpp +++ b/indra/llcommon/llworkerthread.cpp @@ -81,7 +81,7 @@ void LLWorkerThread::clearDeleteList() } // virtual -S32 LLWorkerThread::update(U32 max_time_ms) +S32 LLWorkerThread::update(F32 max_time_ms) { S32 res = LLQueuedThread::update(max_time_ms); // Delete scheduled workers diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h index 78a4781d15..be46394d6e 100644 --- a/indra/llcommon/llworkerthread.h +++ b/indra/llcommon/llworkerthread.h @@ -86,7 +86,7 @@ public: LLWorkerThread(const std::string& name, bool threaded = true, bool should_pause = false); ~LLWorkerThread(); - /*virtual*/ S32 update(U32 max_time_ms); + /*virtual*/ S32 update(F32 max_time_ms); handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority = PRIORITY_NORMAL); -- cgit v1.3 From 4ec112bfce19d4bf09ef79b3b3195dda24148730 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 15 Dec 2011 21:39:48 -0700 Subject: fix for SH-2738 and SH-2777, might also help SH-2723: heap corruption SH-2738: Texture fetching freezes due to LLcurl SH-2777: viewer crashed on logout in LLCurl::Easy::releaseEasyHandle --- indra/llcommon/llthread.h | 7 ++++-- indra/llmessage/llcurl.cpp | 63 ++++++++++++++++++++++++++++------------------ indra/llmessage/llcurl.h | 2 ++ 3 files changed, 45 insertions(+), 27 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 40291a2569..f0e0de6173 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -187,11 +187,14 @@ public: LLMutexLock(LLMutex* mutex) { mMutex = mutex; - mMutex->lock(); + + if(mMutex) + mMutex->lock(); } ~LLMutexLock() { - mMutex->unlock(); + if(mMutex) + mMutex->unlock(); } private: LLMutex* mMutex; diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index ce0632668c..874f4673ca 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -219,11 +219,15 @@ namespace boost std::set LLCurl::Easy::sFreeHandles; std::set LLCurl::Easy::sActiveHandles; +LLMutex* LLCurl::Easy::sHandleMutexp = NULL ; //static CURL* LLCurl::Easy::allocEasyHandle() { CURL* ret = NULL; + + LLMutexLock lock(sHandleMutexp) ; + if (sFreeHandles.empty()) { ret = curl_easy_init(); @@ -251,6 +255,7 @@ void LLCurl::Easy::releaseEasyHandle(CURL* handle) llerrs << "handle cannot be NULL!" << llendl; } + LLMutexLock lock(sHandleMutexp) ; if (sActiveHandles.find(handle) != sActiveHandles.end()) { sActiveHandles.erase(handle); @@ -519,7 +524,8 @@ LLCurl::Multi::Multi() mState(STATE_READY), mDead(FALSE), mMutexp(NULL), - mDeletionMutexp(NULL) + mDeletionMutexp(NULL), + mEasyMutexp(NULL) { mCurlMultiHandle = curl_multi_init(); if (!mCurlMultiHandle) @@ -534,6 +540,7 @@ LLCurl::Multi::Multi() { mMutexp = new LLMutex(NULL) ; mDeletionMutexp = new LLMutex(NULL) ; + mEasyMutexp = new LLMutex(NULL) ; } LLCurl::getCurlThread()->addMulti(this) ; @@ -563,6 +570,8 @@ LLCurl::Multi::~Multi() mMutexp = NULL ; delete mDeletionMutexp ; mDeletionMutexp = NULL ; + delete mEasyMutexp ; + mEasyMutexp = NULL ; --gCurlMultiCount; } @@ -585,17 +594,9 @@ void LLCurl::Multi::unlock() void LLCurl::Multi::markDead() { - if(mDeletionMutexp) - { - mDeletionMutexp->lock() ; - } - + LLMutexLock lock(mDeletionMutexp) ; + mDead = TRUE ; - - if(mDeletionMutexp) - { - mDeletionMutexp->unlock() ; - } } void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state) @@ -655,10 +656,8 @@ CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue) //return true if dead bool LLCurl::Multi::doPerform() { - if(mDeletionMutexp) - { - mDeletionMutexp->lock() ; - } + LLMutexLock lock(mDeletionMutexp) ; + bool dead = mDead ; if(mDead) @@ -675,6 +674,7 @@ bool LLCurl::Multi::doPerform() call_count < MULTI_PERFORM_CALL_REPEAT; call_count++) { + LLMutexLock lock(mMutexp) ; CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q); if (CURLM_CALL_MULTI_PERFORM != code || q == 0) { @@ -688,11 +688,6 @@ bool LLCurl::Multi::doPerform() setState(STATE_COMPLETED) ; } - if(mDeletionMutexp) - { - mDeletionMutexp->unlock() ; - } - return dead ; } @@ -743,19 +738,21 @@ S32 LLCurl::Multi::process() LLCurl::Easy* LLCurl::Multi::allocEasy() { - Easy* easy = 0; + Easy* easy = 0; if (mEasyFreeList.empty()) - { + { easy = Easy::getEasy(); } else { + LLMutexLock lock(mEasyMutexp) ; easy = *(mEasyFreeList.begin()); mEasyFreeList.erase(easy); } if (easy) { + LLMutexLock lock(mEasyMutexp) ; mEasyActiveList.insert(easy); mEasyActiveMap[easy->getCurlHandle()] = easy; } @@ -764,6 +761,7 @@ LLCurl::Easy* LLCurl::Multi::allocEasy() bool LLCurl::Multi::addEasy(Easy* easy) { + LLMutexLock lock(mMutexp) ; CURLMcode mcode = curl_multi_add_handle(mCurlMultiHandle, easy->getCurlHandle()); check_curl_multi_code(mcode); //if (mcode != CURLM_OK) @@ -776,22 +774,30 @@ bool LLCurl::Multi::addEasy(Easy* easy) void LLCurl::Multi::easyFree(Easy* easy) { + mEasyMutexp->lock() ; mEasyActiveList.erase(easy); mEasyActiveMap.erase(easy->getCurlHandle()); + if (mEasyFreeList.size() < EASY_HANDLE_POOL_SIZE) - { - easy->resetState(); + { mEasyFreeList.insert(easy); + mEasyMutexp->unlock() ; + + easy->resetState(); } else { + mEasyMutexp->unlock() ; delete easy; } } void LLCurl::Multi::removeEasy(Easy* easy) { - check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle())); + { + LLMutexLock lock(mMutexp) ; + check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle())); + } easyFree(easy); } @@ -1290,6 +1296,10 @@ void LLCurl::initClass(bool multi_threaded) #endif sCurlThread = new LLCurlThread(multi_threaded) ; + if(multi_threaded) + { + Easy::sHandleMutexp = new LLMutex(NULL) ; + } } void LLCurl::cleanupClass() @@ -1319,6 +1329,9 @@ void LLCurl::cleanupClass() Easy::sFreeHandles.clear(); + delete Easy::sHandleMutexp ; + Easy::sHandleMutexp = NULL ; + llassert(Easy::sActiveHandles.empty()); } diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 2c95279438..eb814bc608 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -253,6 +253,7 @@ private: static std::set sFreeHandles; static std::set sActiveHandles; + static LLMutex* sHandleMutexp ; }; class LLCurl::Multi @@ -316,6 +317,7 @@ private: BOOL mDead ; LLMutex* mMutexp ; LLMutex* mDeletionMutexp ; + LLMutex* mEasyMutexp ; }; class LLCurlThread : public LLQueuedThread -- cgit v1.3 From 1fb6dbbf8061c89131669286fef9940af5dffc76 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Mon, 9 Jan 2012 12:26:57 -0500 Subject: Backed out changeset 4fd359f2f1c3 --- indra/llcommon/llversionviewer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index 7bba3d298f..ec378761c2 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 = 7; +const S32 LL_VERSION_PATCH = 6; const S32 LL_VERSION_BUILD = 0; const char * const LL_CHANNEL = "Second Life Developer"; -- cgit v1.3 From 3dfb1536fa3bb85f6648a76591e80c3feea9eb83 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Mon, 9 Jan 2012 08:41:36 -0500 Subject: increment viewer version to 3.2.7 --- indra/llcommon/llversionviewer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index ec378761c2..7bba3d298f 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 = 6; +const S32 LL_VERSION_PATCH = 7; const S32 LL_VERSION_BUILD = 0; const char * const LL_CHANNEL = "Second Life Developer"; -- cgit v1.3 From a47e9bd97b9855ca8bb3309a73d33d9ae593fd7d Mon Sep 17 00:00:00 2001 From: Vadim ProductEngine Date: Tue, 10 Jan 2012 16:35:36 +0200 Subject: EXP-1525 FIXED Potential fix for a crash at shutdown: added some error handling to saving inventory cache. --- indra/llcommon/llsys.cpp | 18 ++++++++++++++---- indra/newview/llinventorymodel.h | 1 + 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 19075afa68..6073bcd0a6 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -1364,11 +1364,21 @@ BOOL gzip_file(const std::string& srcfile, const std::string& dstfile) src = LLFile::fopen(srcfile, "rb"); /* Flawfinder: ignore */ if (! src) goto err; - do + while ((bytes = (S32)fread(buffer, sizeof(U8), COMPRESS_BUFFER_SIZE, src)) > 0) { - bytes = (S32)fread(buffer, sizeof(U8), COMPRESS_BUFFER_SIZE,src); - gzwrite(dst, buffer, bytes); - } while(feof(src) == 0); + if (gzwrite(dst, buffer, bytes) <= 0) + { + llwarns << "gzwrite failed: " << gzerror(dst, NULL) << llendl; + goto err; + } + } + + if (ferror(src)) + { + llwarns << "Error reading " << srcfile << llendl; + goto err; + } + gzclose(dst); dst = NULL; #if LL_WINDOWS diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 340c1b0c22..f36ae50272 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -64,6 +64,7 @@ class LLInventoryCollectFunctor; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLInventoryModel { + LOG_CLASS(LLInventoryModel); public: friend class LLInventoryModelFetchDescendentsResponder; -- cgit v1.3 From 64c45cbd1ace677456db56d1a506f2fe44b6e9c6 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 17 Jan 2012 10:39:14 -0500 Subject: increment viewer version to 3.2.8 --- indra/llcommon/llversionviewer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index 7bba3d298f..99ab053b25 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 = 7; +const S32 LL_VERSION_PATCH = 8; const S32 LL_VERSION_BUILD = 0; const char * const LL_CHANNEL = "Second Life Developer"; -- cgit v1.3 From 9e6a5d721193f181c39e58fe00073bece74b081a Mon Sep 17 00:00:00 2001 From: Xiaohong Bao 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/llcommon') 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 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 segments; if(copyIntoBuffers(channel, src, len, segments)) @@ -293,6 +347,8 @@ bool LLBufferArray::insertAfter( { LLMemType m1(LLMemType::MTYPE_IO_BUFFER); std::vector 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(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& 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 #include +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.3 From 0e609cc95b08c28bd51f5ab48160fd93df7a6b28 Mon Sep 17 00:00:00 2001 From: Oz Linden 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/llcommon') 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.3