Thrift: C++ peek() method and TException not Exception
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664876 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/transport/TSocket.cpp b/lib/cpp/src/transport/TSocket.cpp
index de3bea7..8b9048c 100644
--- a/lib/cpp/src/transport/TSocket.cpp
+++ b/lib/cpp/src/transport/TSocket.cpp
@@ -43,6 +43,8 @@
lingerOn_(1),
lingerVal_(0),
noDelay_(1) {
+ recvTimeval_.tv_sec = (int)(recvTimeout_/1000);
+ recvTimeval_.tv_usec = (int)((recvTimeout_%1000)*1000);
}
TSocket::TSocket(int socket) :
@@ -55,6 +57,8 @@
lingerOn_(1),
lingerVal_(0),
noDelay_(1) {
+ recvTimeval_.tv_sec = (int)(recvTimeout_/1000);
+ recvTimeval_.tv_usec = (int)((recvTimeout_%1000)*1000);
}
TSocket::~TSocket() {
@@ -65,6 +69,20 @@
return (socket_ > 0);
}
+bool TSocket::peek() {
+ if (!isOpen()) {
+ return false;
+ }
+ uint8_t buf;
+ int r = recv(socket_, &buf, 1, MSG_PEEK);
+ if (r == -1) {
+ perror("TSocket::peek()");
+ close();
+ throw TTransportException(TTX_UNKNOWN, "recv() ERROR:" + errno);
+ }
+ return (r > 0);
+}
+
void TSocket::open() {
// Create socket
socket_ = socket(AF_INET, SOCK_STREAM, 0);
@@ -322,12 +340,14 @@
void TSocket::setRecvTimeout(int ms) {
recvTimeout_ = ms;
+ recvTimeval_.tv_sec = (int)(recvTimeout_/1000);
+ recvTimeval_.tv_usec = (int)((recvTimeout_%1000)*1000);
if (socket_ <= 0) {
return;
}
- struct timeval r = {(int)(recvTimeout_/1000),
- (int)((recvTimeout_%1000)*1000)};
+ // Copy because select may modify
+ struct timeval r = recvTimeval_;
int ret = setsockopt(socket_, SOL_SOCKET, SO_RCVTIMEO, &r, sizeof(r));
if (ret == -1) {
perror("TSocket::setRecvTimeout()");
diff --git a/lib/cpp/src/transport/TSocket.h b/lib/cpp/src/transport/TSocket.h
index b946b6a..8137984 100644
--- a/lib/cpp/src/transport/TSocket.h
+++ b/lib/cpp/src/transport/TSocket.h
@@ -2,6 +2,7 @@
#define _THRIFT_TRANSPORT_TSOCKET_H_ 1
#include <string>
+#include <sys/time.h>
#include "TTransport.h"
#include "TServerSocket.h"
@@ -45,6 +46,11 @@
bool isOpen();
/**
+ * Calls select on the socket to see if there is more data available.
+ */
+ bool peek();
+
+ /**
* Creates and opens the UNIX socket.
*
* @throws TTransportException If the socket could not connect
@@ -131,6 +137,9 @@
/** Nodelay */
bool noDelay_;
+
+ /** Recv timeout timeval */
+ struct timeval recvTimeval_;
};
}}} // facebook::thrift::transport
diff --git a/lib/cpp/src/transport/TTransport.h b/lib/cpp/src/transport/TTransport.h
index 7b4cbe1..5e4ae6b 100644
--- a/lib/cpp/src/transport/TTransport.h
+++ b/lib/cpp/src/transport/TTransport.h
@@ -24,7 +24,21 @@
/**
* Whether this transport is open.
*/
- virtual bool isOpen() { return false; }
+ virtual bool isOpen() {
+ return false;
+ }
+
+ /**
+ * Tests whether there is more data to read or if the remote side is
+ * still open. By default this is true whenever the transport is open,
+ * but implementations should add logic to test for this condition where
+ * possible (i.e. on a socket).
+ * This is used by a server to check if it should listen for another
+ * request.
+ */
+ virtual bool peek() {
+ return isOpen();
+ }
/**
* Opens the transport for communications.
diff --git a/lib/cpp/src/transport/TTransportException.h b/lib/cpp/src/transport/TTransportException.h
index c54084d..e02eb70 100644
--- a/lib/cpp/src/transport/TTransportException.h
+++ b/lib/cpp/src/transport/TTransportException.h
@@ -23,21 +23,25 @@
*
* @author Mark Slee <mcslee@facebook.com>
*/
-class TTransportException {
+class TTransportException : public facebook::thrift::TException {
public:
TTransportException() :
- type_(TTX_UNKNOWN), message_() {}
+ facebook::thrift::TException(),
+ type_(TTX_UNKNOWN) {}
TTransportException(TTransportExceptionType type) :
- type_(type), message_() {}
+ facebook::thrift::TException(),
+ type_(type) {}
- TTransportException(std::string message) :
- type_(TTX_UNKNOWN), message_(message) {}
+ TTransportException(const std::string message) :
+ facebook::thrift::TException(message),
+ type_(TTX_UNKNOWN) {}
- TTransportException(TTransportExceptionType type, std::string message) :
- type_(type), message_(message) {}
+ TTransportException(TTransportExceptionType type, const std::string message) :
+ facebook::thrift::TException(message),
+ type_(type) {}
- ~TTransportException() {}
+ virtual ~TTransportException() throw() {}
/**
* Returns an error code that provides information about the type of error
@@ -45,21 +49,14 @@
*
* @return Error code
*/
- TTransportExceptionType getType() { return type_; }
+ TTransportExceptionType getType() {
+ return type_;
+ }
- /**
- * Returns an informative message about what caused this error.
- *
- * @return Error string
- */
- const std::string& getMessage() { return message_; }
-
protected:
/** Error code */
TTransportExceptionType type_;
- /** Description */
- std::string message_;
};
}}} // facebook::thrift::transport
diff --git a/lib/cpp/src/transport/TTransportUtils.cpp b/lib/cpp/src/transport/TTransportUtils.cpp
index d9f4775..02454e3 100644
--- a/lib/cpp/src/transport/TTransportUtils.cpp
+++ b/lib/cpp/src/transport/TTransportUtils.cpp
@@ -16,7 +16,6 @@
buf += rLen_-rPos_;
}
// Get more from underlying transport up to buffer size
- // TODO: should this be a readAll?
rLen_ = transport_->read(rBuf_, rBufSize_);
rPos_ = 0;
}
diff --git a/lib/cpp/src/transport/TTransportUtils.h b/lib/cpp/src/transport/TTransportUtils.h
index 8d8d093..a8003cf 100644
--- a/lib/cpp/src/transport/TTransportUtils.h
+++ b/lib/cpp/src/transport/TTransportUtils.h
@@ -71,6 +71,14 @@
return transport_->isOpen();
}
+ bool peek() {
+ if (rPos_ >= rLen_) {
+ rLen_ = transport_->read(rBuf_, rBufSize_);
+ rPos_ = 0;
+ }
+ return (rLen_ > rPos_);
+ }
+
void open() {
transport_->open();
}
@@ -177,6 +185,13 @@
return transport_->isOpen();
}
+ bool peek() {
+ if (rPos_ < rLen_) {
+ return true;
+ }
+ return transport_->peek();
+ }
+
void close() {
transport_->close();
}
@@ -260,7 +275,10 @@
return true;
}
-
+ bool peek() {
+ return (rPos_ < wPos_);
+ }
+
void open() {}
void close() {}