Author: dreiss
Date: Wed Oct 6 17:10:46 2010
New Revision: 1005165
URL: http://svn.apache.org/viewvc?rev=1005165&view=rev
Log:
THRIFT-926. cpp: TMemoryBuffer: Uphold the strong exception safety guarantee
Previously, if we had a realloc failure when growing a TMemoryBuffer, we
would leave the buffer in an invalid state (bufferSize_ would reflect
the desired size, rather than the actual size). Now, we make no change
to any member variables if realloc fails.
Modified:
incubator/thrift/trunk/lib/cpp/src/transport/TBufferTransports.cpp
Modified: incubator/thrift/trunk/lib/cpp/src/transport/TBufferTransports.cpp
URL:
http://svn.apache.org/viewvc/incubator/thrift/trunk/lib/cpp/src/transport/TBufferTransports.cpp?rev=1005165&r1=1005164&r2=1005165&view=diff
==============================================================================
--- incubator/thrift/trunk/lib/cpp/src/transport/TBufferTransports.cpp
(original)
+++ incubator/thrift/trunk/lib/cpp/src/transport/TBufferTransports.cpp Wed Oct
6 17:10:46 2010
@@ -324,24 +324,25 @@ void TMemoryBuffer::ensureCanWrite(uint3
}
// Grow the buffer as necessary.
+ uint32_t new_size = bufferSize_;
while (len > avail) {
- bufferSize_ *= 2;
- wBound_ = buffer_ + bufferSize_;
- avail = available_write();
+ new_size = new_size > 0 ? new_size * 2 : 1;
+ avail = available_write() + (new_size - bufferSize_);
}
// Allocate into a new pointer so we don't bork ours if it fails.
- void* new_buffer = std::realloc(buffer_, bufferSize_);
+ void* new_buffer = std::realloc(buffer_, new_size);
if (new_buffer == NULL) {
throw TTransportException("Out of memory.");
}
+ bufferSize_ = new_size;
ptrdiff_t offset = (uint8_t*)new_buffer - buffer_;
buffer_ += offset;
rBase_ += offset;
rBound_ += offset;
wBase_ += offset;
- wBound_ += offset;
+ wBound_ = buffer_ + bufferSize_;
}
void TMemoryBuffer::writeSlow(const uint8_t* buf, uint32_t len) {