From e4db03d1106a3bb381942471be9fdce72f9e88b9 Mon Sep 17 00:00:00 2001 From: David Reiss Date: Tue, 8 Apr 2008 05:06:59 +0000 Subject: [PATCH] Add TFDTransport: a dead-simple wrapper around a file-descriptor. git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665644 13f79535-47bb-0310-9956-ffa450edef68 --- lib/cpp/Makefile.am | 2 + lib/cpp/src/transport/TFDTransport.cpp | 64 ++++++++++++++++++++++++++ lib/cpp/src/transport/TFDTransport.h | 61 ++++++++++++++++++++++++ test/Makefile.am | 10 ++++ test/TFDTransportTest.cpp | 37 +++++++++++++++ 5 files changed, 174 insertions(+) create mode 100644 lib/cpp/src/transport/TFDTransport.cpp create mode 100644 lib/cpp/src/transport/TFDTransport.h create mode 100644 test/TFDTransportTest.cpp diff --git a/lib/cpp/Makefile.am b/lib/cpp/Makefile.am index 571c4ff2..feaebaf7 100644 --- a/lib/cpp/Makefile.am +++ b/lib/cpp/Makefile.am @@ -34,6 +34,7 @@ libthrift_la_SOURCES = src/Thrift.cpp \ src/protocol/TJSONProtocol.cpp \ src/protocol/TBase64Utils.cpp \ src/transport/TTransportException.cpp \ + src/transport/TFDTransport.cpp \ src/transport/TFileTransport.cpp \ src/transport/THttpClient.cpp \ src/transport/TSocket.cpp \ @@ -94,6 +95,7 @@ include_protocol_HEADERS = \ include_transportdir = $(include_thriftdir)/transport include_transport_HEADERS = \ + src/transport/TFDTransport.h \ src/transport/TFileTransport.h \ src/transport/TServerSocket.h \ src/transport/TServerTransport.h \ diff --git a/lib/cpp/src/transport/TFDTransport.cpp b/lib/cpp/src/transport/TFDTransport.cpp new file mode 100644 index 00000000..bbdcb193 --- /dev/null +++ b/lib/cpp/src/transport/TFDTransport.cpp @@ -0,0 +1,64 @@ +// Copyright (c) 2006- Facebook +// Distributed under the Thrift Software License +// +// See accompanying file LICENSE or visit the Thrift site at: +// http://developers.facebook.com/thrift/ + +#include +#include + +#include + +#include + +using namespace std; + +namespace facebook { namespace thrift { namespace transport { + +void TFDTransport::close() { + if (!isOpen()) { + return; + } + + int rv = ::close(fd_); + int errno_copy = errno; + fd_ = -1; + // Have to check uncaught_exception because this is called in the destructor. + if (rv < 0 && !std::uncaught_exception()) { + throw TTransportException(TTransportException::UNKNOWN, + "TFDTransport::close()", + errno_copy); + } +} + +uint32_t TFDTransport::read(uint8_t* buf, uint32_t len) { + ssize_t rv = ::read(fd_, buf, len); + if (rv < 0) { + int errno_copy = errno; + throw TTransportException(TTransportException::UNKNOWN, + "TFDTransport::read()", + errno_copy); + } + return rv; +} + +void TFDTransport::write(const uint8_t* buf, uint32_t len) { + while (len > 0) { + ssize_t rv = ::write(fd_, buf, len); + + if (rv < 0) { + int errno_copy = errno; + throw TTransportException(TTransportException::UNKNOWN, + "TFDTransport::write()", + errno_copy); + } else if (rv == 0) { + throw TTransportException(TTransportException::END_OF_FILE, + "TFDTransport::write()"); + } + + buf += rv; + len -= rv; + } +} + +}}} // facebook::thrift::transport diff --git a/lib/cpp/src/transport/TFDTransport.h b/lib/cpp/src/transport/TFDTransport.h new file mode 100644 index 00000000..e70f987f --- /dev/null +++ b/lib/cpp/src/transport/TFDTransport.h @@ -0,0 +1,61 @@ +// Copyright (c) 2006- Facebook +// Distributed under the Thrift Software License +// +// See accompanying file LICENSE or visit the Thrift site at: +// http://developers.facebook.com/thrift/ + +#ifndef _THRIFT_TRANSPORT_TFDTRANSPORT_H_ +#define _THRIFT_TRANSPORT_TFDTRANSPORT_H_ 1 + +#include +#include + +#include "TTransport.h" +#include "TServerSocket.h" + +namespace facebook { namespace thrift { namespace transport { + +/** + * Dead-simple wrapper around a file descriptor. + * + * @author David Reiss + */ +class TFDTransport : public TTransport { + public: + enum ClosePolicy { + NO_CLOSE_ON_DESTROY = 0, + CLOSE_ON_DESTROY = 1, + }; + + TFDTransport(int fd, ClosePolicy close_policy = NO_CLOSE_ON_DESTROY) + : fd_(fd) + , close_policy_(close_policy) + {} + + ~TFDTransport() { + if (close_policy_ == CLOSE_ON_DESTROY) { + close(); + } + } + + bool isOpen() { return fd_ >= 0; } + + void open() {} + + void close(); + + uint32_t read(uint8_t* buf, uint32_t len); + + void write(const uint8_t* buf, uint32_t len); + + void setFD(int fd) { fd_ = fd; } + int getFD() { return fd_; } + + protected: + int fd_; + ClosePolicy close_policy_; +}; + +}}} // facebook::thrift::transport + +#endif // #ifndef _THRIFT_TRANSPORT_TFDTRANSPORT_H_ diff --git a/test/Makefile.am b/test/Makefile.am index 5de2f1b2..5490de84 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -27,6 +27,7 @@ Benchmark_SOURCES = \ Benchmark_LDADD = libtestgencpp.la check_PROGRAMS = \ + TFDTransportTest \ DebugProtoTest \ JSONProtoTest \ OptionalRequiredTest \ @@ -42,6 +43,15 @@ UnitTests_SOURCES = \ UnitTests_LDADD = libtestgencpp.la +# +# TFDTransportTest +# +TFDTransportTest_SOURCES = \ + TFDTransportTest.cpp + +TFDTransportTest_LDADD = \ + $(top_srcdir)/lib/cpp/libthrift.la + # # DebugProtoTest # diff --git a/test/TFDTransportTest.cpp b/test/TFDTransportTest.cpp new file mode 100644 index 00000000..dfc2d277 --- /dev/null +++ b/test/TFDTransportTest.cpp @@ -0,0 +1,37 @@ +#include +#include +#include +#include +using facebook::thrift::transport::TTransportException; +using facebook::thrift::transport::TFDTransport; + +class DummyException : std::exception { +}; + +int main() { + { + TFDTransport t(256, TFDTransport::NO_CLOSE_ON_DESTROY); + } + + try { + { + TFDTransport t(256, TFDTransport::CLOSE_ON_DESTROY); + } + std::abort(); + } catch (TTransportException) { + } + + try { + { + TFDTransport t(256, TFDTransport::CLOSE_ON_DESTROY); + throw DummyException(); + } + std::abort(); + } catch (TTransportException&) { + abort(); + } catch (DummyException&) { + } + + return 0; + +} -- 2.17.1