Fix a bug in TPipedTransport that broke pipelining.

Previously, TPipedTransport wrote it's full buffer to the "pipe" and
fully reset its buffer on a readEnd.  This assumed that the buffer was
fully read at that point.  This is not the case if requests are pipelined.
This change makes it only pipe out the portion that has been read and
copy the unread portion to the beginning of the buffer.

Also add a test that verifies the new functionality.


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665646 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
David Reiss 2008-04-08 05:07:26 +00:00
parent bbdb06eb24
commit 1ffb61beaa
3 changed files with 51 additions and 3 deletions

View File

@ -616,15 +616,18 @@ class TPipedTransport : virtual public TTransport {
void readEnd() {
if (pipeOnRead_) {
dstTrans_->write(rBuf_, rLen_);
dstTrans_->write(rBuf_, rPos_);
dstTrans_->flush();
}
srcTrans_->readEnd();
// reset state
rLen_ = 0;
// If requests are being pipelined, copy down our read-ahead data,
// then reset our state.
int read_ahead = rLen_ - rPos_;
memcpy(rBuf_, rBuf_ + rPos_, read_ahead);
rPos_ = 0;
rLen_ = read_ahead;
}
void write(const uint8_t* buf, uint32_t len);

View File

@ -28,6 +28,7 @@ Benchmark_LDADD = libtestgencpp.la
check_PROGRAMS = \
TFDTransportTest \
TPipedTransportTest \
DebugProtoTest \
JSONProtoTest \
OptionalRequiredTest \
@ -52,6 +53,16 @@ TFDTransportTest_SOURCES = \
TFDTransportTest_LDADD = \
$(top_srcdir)/lib/cpp/libthrift.la
#
# TPipedTransportTest
#
TPipedTransportTest_SOURCES = \
TPipedTransportTest.cpp
TPipedTransportTest_LDADD = \
$(top_srcdir)/lib/cpp/libthrift.la
#
# DebugProtoTest
#

View File

@ -0,0 +1,34 @@
#include <cstdlib>
#include <stdexcept>
#include <Thrift.h>
#include <transport/TTransportUtils.h>
using namespace std;
using boost::shared_ptr;
using facebook::thrift::transport::TTransportException;
using facebook::thrift::transport::TPipedTransport;
using facebook::thrift::transport::TMemoryBuffer;
int main() {
shared_ptr<TMemoryBuffer> underlying(new TMemoryBuffer);
shared_ptr<TMemoryBuffer> pipe(new TMemoryBuffer);
shared_ptr<TPipedTransport> trans(new TPipedTransport(underlying, pipe));
uint8_t buffer[4];
underlying->write((uint8_t*)"abcd", 4);
trans->readAll(buffer, 2);
assert( string((char*)buffer, 2) == "ab" );
trans->readEnd();
assert( pipe->getBufferAsString() == "ab" );
pipe->resetBuffer();
underlying->write((uint8_t*)"ef", 2);
trans->readAll(buffer, 2);
assert( string((char*)buffer, 2) == "cd" );
trans->readAll(buffer, 2);
assert( string((char*)buffer, 2) == "ef" );
trans->readEnd();
assert( pipe->getBufferAsString() == "cdef" );
return 0;
}