THRIFT-926. cpp: Add configurable buffer recycling for TNonblockingServer
Add methods to TNonblockingServer to set the maximum size of idle read
and write buffers and the check interval (in calls). When checked, if
the buffers are larger than the configured maximum, they will be resized
down the to maximum size.
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@1005164 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/server/TNonblockingServer.cpp b/lib/cpp/src/server/TNonblockingServer.cpp
index 73edd93..1bf4e68 100644
--- a/lib/cpp/src/server/TNonblockingServer.cpp
+++ b/lib/cpp/src/server/TNonblockingServer.cpp
@@ -112,9 +112,11 @@
writeBuffer_ = NULL;
writeBufferSize_ = 0;
writeBufferPos_ = 0;
+ largestWriteBufferSize_ = 0;
socketState_ = SOCKET_RECV;
appState_ = APP_INIT;
+ callsForResize_ = 0;
// Set flags, which also registers the event
setFlags(eventFlags);
@@ -342,6 +344,16 @@
goto LABEL_APP_INIT;
case APP_SEND_RESULT:
+ // it's now safe to perform buffer size housekeeping.
+ if (writeBufferSize_ > largestWriteBufferSize_) {
+ largestWriteBufferSize_ = writeBufferSize_;
+ }
+ if (server_->getResizeBufferEveryN() > 0
+ && ++callsForResize_ >= server_->getResizeBufferEveryN()) {
+ checkIdleBufferMemLimit(server_->getIdleReadBufferLimit(),
+ server_->getIdleWriteBufferLimit());
+ callsForResize_ = 0;
+ }
// N.B.: We also intentionally fall through here into the INIT state!
@@ -486,15 +498,22 @@
server_->returnConnection(this);
}
-void TConnection::checkIdleBufferMemLimit(size_t limit) {
- if (readBufferSize_ > limit) {
- readBufferSize_ = limit;
+void TConnection::checkIdleBufferMemLimit(size_t readLimit,
+ size_t writeLimit) {
+ if (readLimit > 0 && readBufferSize_ > readLimit) {
+ readBufferSize_ = readLimit;
readBuffer_ = (uint8_t*)std::realloc(readBuffer_, readBufferSize_);
if (readBuffer_ == NULL) {
GlobalOutput("TConnection::checkIdleBufferMemLimit() realloc");
close();
}
}
+
+ if (writeLimit > 0 && largestWriteBufferSize_ > writeLimit) {
+ // just start over
+ outputTransport_->resetBuffer(NULL, 0, TMemoryBuffer::TAKE_OWNERSHIP);
+ largestWriteBufferSize_ = 0;
+ }
}
TNonblockingServer::~TNonblockingServer() {
@@ -546,7 +565,7 @@
(connectionStack_.size() >= connectionStackLimit_)) {
delete connection;
} else {
- connection->checkIdleBufferMemLimit(idleBufferMemLimit_);
+ connection->checkIdleBufferMemLimit(idleReadBufferLimit_, idleWriteBufferLimit_);
connectionStack_.push(connection);
}
}