diff options
author | Jacek Antonelli | 2008-08-15 23:44:54 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:54 -0500 |
commit | b2afb8800bb033a04bb3ecdf0363068d56648ef1 (patch) | |
tree | 3568129b5bbddb47cd39d622b4137a8fbff4abaf /linden/indra/llmessage/llbuffer.cpp | |
parent | Second Life viewer sources 1.14.0.1 (diff) | |
download | meta-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.cpp | 121 |
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 | ||
88 | bool 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 | */ |
91 | LLHeapBuffer::LLHeapBuffer() | 100 | LLHeapBuffer::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 | ||
98 | LLHeapBuffer::LLHeapBuffer(S32 size) | 111 | LLHeapBuffer::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 | ||
104 | LLHeapBuffer::LLHeapBuffer(const U8* src, S32 len) | 121 | LLHeapBuffer::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 | 148 | S32 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 |
140 | bool LLHeapBuffer::createSegment( | 154 | bool LLHeapBuffer::createSegment( |
@@ -158,9 +172,47 @@ bool LLHeapBuffer::createSegment( | |||
158 | return true; | 172 | return true; |
159 | } | 173 | } |
160 | 174 | ||
175 | // virtual | ||
176 | bool 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 | ||
200 | bool 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 | |||
161 | void LLHeapBuffer::allocate(S32 size) | 212 | void 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 | ||
254 | S32 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 | |||
202 | bool LLBufferArray::append(S32 channel, const U8* src, S32 len) | 266 | bool 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 | ||
706 | bool LLBufferArray::eraseSegment(const segment_iterator_t& iter) | 770 | bool 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 | ||