diff options
Diffstat (limited to 'indra/llmessage/llbuffer.cpp')
-rwxr-xr-x[-rw-r--r--] | indra/llmessage/llbuffer.cpp | 153 |
1 files changed, 105 insertions, 48 deletions
diff --git a/indra/llmessage/llbuffer.cpp b/indra/llmessage/llbuffer.cpp index 1ffcecd84e..d07d9980c3 100644..100755 --- a/indra/llmessage/llbuffer.cpp +++ b/indra/llmessage/llbuffer.cpp @@ -4,31 +4,25 @@ * @date 2005-09-20 * @brief Implementation of the segments, buffers, and buffer arrays. * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,8 +30,11 @@ #include "llbuffer.h" #include "llmath.h" -#include "llmemtype.h" #include "llstl.h" +#include "llthread.h" +#include <iterator> + +#define ASSERT_LLBUFFERARRAY_MUTEX_LOCKED() llassert(!mMutexp || mMutexp->isSelfLocked()) /** * LLSegment @@ -47,7 +44,6 @@ LLSegment::LLSegment() : mData(NULL), mSize(0) { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); } LLSegment::LLSegment(S32 channel, U8* data, S32 data_len) : @@ -55,12 +51,10 @@ LLSegment::LLSegment(S32 channel, U8* data, S32 data_len) : mData(data), mSize(data_len) { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); } LLSegment::~LLSegment() { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); } bool LLSegment::isOnChannel(S32 channel) const @@ -107,7 +101,6 @@ LLHeapBuffer::LLHeapBuffer() : mNextFree(NULL), mReclaimedBytes(0) { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); const S32 DEFAULT_HEAP_BUFFER_SIZE = 16384; allocate(DEFAULT_HEAP_BUFFER_SIZE); } @@ -118,7 +111,6 @@ LLHeapBuffer::LLHeapBuffer(S32 size) : mNextFree(NULL), mReclaimedBytes(0) { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); allocate(size); } @@ -128,7 +120,6 @@ LLHeapBuffer::LLHeapBuffer(const U8* src, S32 len) : mNextFree(NULL), mReclaimedBytes(0) { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); if((len > 0) && src) { allocate(len); @@ -142,7 +133,6 @@ LLHeapBuffer::LLHeapBuffer(const U8* src, S32 len) : // virtual LLHeapBuffer::~LLHeapBuffer() { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); delete[] mBuffer; mBuffer = NULL; mSize = 0; @@ -160,7 +150,6 @@ bool LLHeapBuffer::createSegment( S32 size, LLSegment& segment) { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); // get actual size of the segment. S32 actual_size = llmin(size, (mSize - S32(mNextFree - mBuffer))); @@ -192,8 +181,8 @@ bool LLHeapBuffer::reclaimSegment(const LLSegment& segment) } else if(mReclaimedBytes > mSize) { - llwarns << "LLHeapBuffer reclaimed more memory than allocated." - << " This is probably programmer error." << llendl; + LL_WARNS() << "LLHeapBuffer reclaimed more memory than allocated." + << " This is probably programmer error." << LL_ENDL; } return true; } @@ -215,7 +204,6 @@ bool LLHeapBuffer::containsSegment(const LLSegment& segment) const void LLHeapBuffer::allocate(S32 size) { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); mReclaimedBytes = 0; mBuffer = new U8[size]; if(mBuffer) @@ -230,15 +218,16 @@ void LLHeapBuffer::allocate(S32 size) * LLBufferArray */ LLBufferArray::LLBufferArray() : - mNextBaseChannel(0) + mNextBaseChannel(0), + mMutexp(NULL) { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); } LLBufferArray::~LLBufferArray() { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); std::for_each(mBuffers.begin(), mBuffers.end(), DeletePointer()); + mBuffers.clear(); + delete mMutexp; } // static @@ -249,14 +238,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(); @@ -269,7 +301,8 @@ S32 LLBufferArray::capacity() const bool LLBufferArray::append(S32 channel, const U8* src, S32 len) { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); + LLMutexLock lock(mMutexp) ; + std::vector<LLSegment> segments; if(copyIntoBuffers(channel, src, len, segments)) { @@ -279,9 +312,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) { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); + std::vector<LLSegment> segments; if(copyIntoBuffers(channel, src, len, segments)) { @@ -297,8 +332,9 @@ bool LLBufferArray::insertAfter( const U8* src, S32 len) { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); std::vector<LLSegment> segments; + + LLMutexLock lock(mMutexp) ; if(mSegments.end() != segment) { ++segment; @@ -311,9 +347,11 @@ bool LLBufferArray::insertAfter( return false; } +//mMutexp should be locked before calling this. LLBufferArray::segment_iterator_t LLBufferArray::splitAfter(U8* address) { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); + segment_iterator_t end = mSegments.end(); segment_iterator_t it = getSegment(address); if(it == end) @@ -341,21 +379,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) { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); segment_iterator_t rv = mSegments.begin(); segment_iterator_t end = mSegments.end(); if(!address) @@ -401,8 +444,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) { @@ -420,9 +465,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) { @@ -472,6 +519,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) { @@ -513,7 +562,6 @@ U8* LLBufferArray::readAfter( U8* dest, S32& len) const { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); U8* rv = start; if(!dest || len <= 0) { @@ -523,6 +571,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) { @@ -574,7 +624,7 @@ U8* LLBufferArray::seek( U8* start, S32 delta) const { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); const_segment_iterator_t it; const_segment_iterator_t end = mSegments.end(); U8* rv = start; @@ -715,9 +765,12 @@ 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(), @@ -729,14 +782,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) { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); // start at the end of the buffers, because it is the most likely // to have free space. LLSegment segment; @@ -771,9 +827,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) { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); // Find out which buffer contains the segment, and if it is found, // ask it to reclaim the memory. @@ -798,14 +855,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) { - LLMemType m1(LLMemType::MTYPE_IO_BUFFER); + ASSERT_LLBUFFERARRAY_MUTEX_LOCKED(); if(!src || !len) return false; S32 copied = 0; LLSegment segment; |