Better socket timeout and options support for Thrift C++

Summary: Also compile without degugging symbols for the linked library

Reviewed By: aditya


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664810 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/transport/TServerSocket.cc b/lib/cpp/src/transport/TServerSocket.cc
index 75bd504..8a14ea5 100644
--- a/lib/cpp/src/transport/TServerSocket.cc
+++ b/lib/cpp/src/transport/TServerSocket.cc
@@ -1,5 +1,6 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <netinet/tcp.h>
 #include <errno.h>
 
 #include "TSocket.h"
@@ -11,12 +12,31 @@
 using namespace boost;
 
 TServerSocket::TServerSocket(int port) :
-  port_(port), serverSocket_(0), acceptBacklog_(1024) {}
+  port_(port),
+  serverSocket_(0),
+  acceptBacklog_(1024),
+  sendTimeout_(0),
+  recvTimeout_(0) {}
+
+TServerSocket::TServerSocket(int port, int sendTimeout, int recvTimeout) :
+  port_(port),
+  serverSocket_(0),
+  acceptBacklog_(1024),
+  sendTimeout_(sendTimeout),
+  recvTimeout_(recvTimeout) {}
 
 TServerSocket::~TServerSocket() {
   close();
 }
 
+void TServerSocket::setSendTimeout(int sendTimeout) {
+  sendTimeout_ = sendTimeout;
+}
+
+void TServerSocket::setRecvTimeout(int recvTimeout) {
+  recvTimeout_ = recvTimeout;
+}
+
 void TServerSocket::listen() {
   serverSocket_ = socket(AF_INET, SOCK_STREAM, 0);
   if (serverSocket_ == -1) {
@@ -34,6 +54,16 @@
     throw TTransportException(TTX_NOT_OPEN, "Could not set SO_REUSEADDR");
   }
 
+  // Defer accept
+  #ifdef TCP_DEFER_ACCEPT
+  if (-1 == setsockopt(serverSocket_, SOL_SOCKET, TCP_DEFER_ACCEPT,
+                       &one, sizeof(one))) {
+    perror("TServerSocket::listen() TCP_DEFER_ACCEPT");
+    close();
+    throw TTransportException(TTX_NOT_OPEN, "Could not set TCP_DEFER_ACCEPT");
+  }
+  #endif // #ifdef TCP_DEFER_ACCEPT
+
   // Turn linger off, don't want to block on calls to close
   struct linger ling = {0, 0};
   if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_LINGER,
@@ -43,6 +73,14 @@
     throw TTransportException(TTX_NOT_OPEN, "Could not set SO_LINGER");
   }
 
+  // TCP Nodelay, speed over bandwidth
+  if (-1 == setsockopt(serverSocket_, IPPROTO_TCP, TCP_NODELAY,
+                       &one, sizeof(one))) {
+    close();
+    perror("setsockopt TCP_NODELAY");
+    throw TTransportException(TTX_NOT_OPEN, "Could not set TCP_NODELAY");
+  }
+
   // Bind to a port
   struct sockaddr_in addr;
   memset(&addr, 0, sizeof(addr));
@@ -83,7 +121,14 @@
     throw TTransportException(TTX_UNKNOWN, "ERROR:" + errno);
   }
 
-  return shared_ptr<TTransport>(new TSocket(clientSocket));
+  shared_ptr<TSocket> client(new TSocket(clientSocket));
+  if (sendTimeout_ > 0) {
+    client->setSendTimeout(sendTimeout_);
+  }
+  if (recvTimeout_ > 0) {
+    client->setRecvTimeout(recvTimeout_);
+  }                          
+  return client;
 }
 
 void TServerSocket::close() {