aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmessage/llbuffer.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:54 -0500
committerJacek Antonelli2008-08-15 23:44:54 -0500
commitb2afb8800bb033a04bb3ecdf0363068d56648ef1 (patch)
tree3568129b5bbddb47cd39d622b4137a8fbff4abaf /linden/indra/llmessage/llbuffer.cpp
parentSecond Life viewer sources 1.14.0.1 (diff)
downloadmeta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.zip
meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.gz
meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.bz2
meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.xz
Second Life viewer sources 1.15.0.2
Diffstat (limited to 'linden/indra/llmessage/llbuffer.cpp')
-rw-r--r--linden/indra/llmessage/llbuffer.cpp121
1 files changed, 101 insertions, 20 deletions
diff --git a/linden/indra/llmessage/llbuffer.cpp b/linden/indra/llmessage/llbuffer.cpp
index 3dd34a0..ad822bc 100644
--- a/linden/indra/llmessage/llbuffer.cpp
+++ b/linden/indra/llmessage/llbuffer.cpp
@@ -6,6 +6,7 @@
6 * 6 *
7 * Copyright (c) 2005-2007, Linden Research, Inc. 7 * Copyright (c) 2005-2007, Linden Research, Inc.
8 * 8 *
9 * Second Life Viewer Source Code
9 * The source code in this file ("Source Code") is provided by Linden Lab 10 * The source code in this file ("Source Code") is provided by Linden Lab
10 * to you under the terms of the GNU General Public License, version 2.0 11 * to you under the terms of the GNU General Public License, version 2.0
11 * ("GPL"), unless you have obtained a separate licensing agreement 12 * ("GPL"), unless you have obtained a separate licensing agreement
@@ -84,24 +85,44 @@ S32 LLSegment::size() const
84 return mSize; 85 return mSize;
85} 86}
86 87
88bool LLSegment::operator==(const LLSegment& rhs) const
89{
90 if((mData != rhs.mData)||(mSize != rhs.mSize)||(mChannel != rhs.mChannel))
91 {
92 return false;
93 }
94 return true;
95}
87 96
88/** 97/**
89 * LLHeapBuffer 98 * LLHeapBuffer
90 */ 99 */
91LLHeapBuffer::LLHeapBuffer() 100LLHeapBuffer::LLHeapBuffer() :
101 mBuffer(NULL),
102 mSize(0),
103 mNextFree(NULL),
104 mReclaimedBytes(0)
92{ 105{
93 LLMemType m1(LLMemType::MTYPE_IO_BUFFER); 106 LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
94 const S32 DEFAULT_HEAP_BUFFER_SIZE = 16384; 107 const S32 DEFAULT_HEAP_BUFFER_SIZE = 16384;
95 allocate(DEFAULT_HEAP_BUFFER_SIZE); 108 allocate(DEFAULT_HEAP_BUFFER_SIZE);
96} 109}
97 110
98LLHeapBuffer::LLHeapBuffer(S32 size) 111LLHeapBuffer::LLHeapBuffer(S32 size) :
112 mBuffer(NULL),
113 mSize(0),
114 mNextFree(NULL),
115 mReclaimedBytes(0)
99{ 116{
100 LLMemType m1(LLMemType::MTYPE_IO_BUFFER); 117 LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
101 allocate(size); 118 allocate(size);
102} 119}
103 120
104LLHeapBuffer::LLHeapBuffer(const U8* src, S32 len) 121LLHeapBuffer::LLHeapBuffer(const U8* src, S32 len) :
122 mBuffer(NULL),
123 mSize(0),
124 mNextFree(NULL),
125 mReclaimedBytes(0)
105{ 126{
106 LLMemType m1(LLMemType::MTYPE_IO_BUFFER); 127 LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
107 if((len > 0) && src) 128 if((len > 0) && src)
@@ -112,12 +133,6 @@ LLHeapBuffer::LLHeapBuffer(const U8* src, S32 len)
112 memcpy(mBuffer, src, len); /*Flawfinder: ignore*/ 133 memcpy(mBuffer, src, len); /*Flawfinder: ignore*/
113 } 134 }
114 } 135 }
115 else
116 {
117 mBuffer = NULL;
118 mSize = 0;
119 mNextFree = NULL;
120 }
121} 136}
122 137
123// virtual 138// virtual
@@ -130,11 +145,10 @@ LLHeapBuffer::~LLHeapBuffer()
130 mNextFree = NULL; 145 mNextFree = NULL;
131} 146}
132 147
133// virtual 148S32 LLHeapBuffer::bytesLeft() const
134//S32 LLHeapBuffer::bytesLeft() const 149{
135//{ 150 return (mSize - (mNextFree - mBuffer));
136// return (mSize - (mNextFree - mBuffer)); 151}
137//}
138 152
139// virtual 153// virtual
140bool LLHeapBuffer::createSegment( 154bool LLHeapBuffer::createSegment(
@@ -158,9 +172,47 @@ bool LLHeapBuffer::createSegment(
158 return true; 172 return true;
159} 173}
160 174
175// virtual
176bool LLHeapBuffer::reclaimSegment(const LLSegment& segment)
177{
178 if(containsSegment(segment))
179 {
180 mReclaimedBytes += segment.size();
181 if(mReclaimedBytes == mSize)
182 {
183 // We have reclaimed all of the memory from this
184 // buffer. Therefore, we can reset the mNextFree to the
185 // start of the buffer, and reset the reclaimed bytes.
186 mReclaimedBytes = 0;
187 mNextFree = mBuffer;
188 }
189 else if(mReclaimedBytes > mSize)
190 {
191 llwarns << "LLHeapBuffer reclaimed more memory than allocated."
192 << " This is probably programmer error." << llendl;
193 }
194 return true;
195 }
196 return false;
197}
198
199// virtual
200bool LLHeapBuffer::containsSegment(const LLSegment& segment) const
201{
202 // *NOTE: this check is fairly simple because heap buffers are
203 // simple contiguous chunks of heap memory.
204 if((mBuffer > segment.data())
205 || ((mBuffer + mSize) < (segment.data() + segment.size())))
206 {
207 return false;
208 }
209 return true;
210}
211
161void LLHeapBuffer::allocate(S32 size) 212void LLHeapBuffer::allocate(S32 size)
162{ 213{
163 LLMemType m1(LLMemType::MTYPE_IO_BUFFER); 214 LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
215 mReclaimedBytes = 0;
164 mBuffer = new U8[size]; 216 mBuffer = new U8[size];
165 if(mBuffer) 217 if(mBuffer)
166 { 218 {
@@ -199,6 +251,18 @@ LLChannelDescriptors LLBufferArray::nextChannel()
199 return rv; 251 return rv;
200} 252}
201 253
254S32 LLBufferArray::capacity() const
255{
256 S32 total = 0;
257 const_buffer_iterator_t iter = mBuffers.begin();
258 const_buffer_iterator_t end = mBuffers.end();
259 for(; iter != end; ++iter)
260 {
261 total += (*iter)->capacity();
262 }
263 return total;
264}
265
202bool LLBufferArray::append(S32 channel, const U8* src, S32 len) 266bool LLBufferArray::append(S32 channel, const U8* src, S32 len)
203{ 267{
204 LLMemType m1(LLMemType::MTYPE_IO_BUFFER); 268 LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
@@ -703,14 +767,31 @@ LLBufferArray::segment_iterator_t LLBufferArray::makeSegment(
703 return send; 767 return send;
704} 768}
705 769
706bool LLBufferArray::eraseSegment(const segment_iterator_t& iter) 770bool LLBufferArray::eraseSegment(const segment_iterator_t& erase_iter)
707{ 771{
708 LLMemType m1(LLMemType::MTYPE_IO_BUFFER); 772 LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
709 // *FIX: in theory, we could reclaim the memory. We are leaking a 773
710 // bit of buffered memory into an unusable but still referenced 774 // Find out which buffer contains the segment, and if it is found,
711 // location. 775 // ask it to reclaim the memory.
712 (void)mSegments.erase(iter); 776 bool rv = false;
713 return true; 777 LLSegment segment(*erase_iter);
778 buffer_iterator_t iter = mBuffers.begin();
779 buffer_iterator_t end = mBuffers.end();
780 for(; iter != end; ++iter)
781 {
782 // We can safely call reclaimSegment on every buffer, and once
783 // it returns true, the segment was found.
784 if((*iter)->reclaimSegment(segment))
785 {
786 rv = true;
787 break;
788 }
789 }
790
791 // No need to get the return value since we are not interested in
792 // the interator retured by the call.
793 (void)mSegments.erase(erase_iter);
794 return rv;
714} 795}
715 796
716 797